When I switched from using Element UI to Element Plus, I encountered a change in how prefix/suffix icons are handled. Now, I had to pass them as components instead of classname strings. Since I prefer using a single custom icon component, I needed to create a vnode and customize it with props before passing it in as the icon prop.
To simplify this process, I decided to create a plugin:
import { createVNode, getCurrentInstance } from 'vue'
export const createComponent = (component, props) => {
try {
if (component?.constructor === String) {
const instance = getCurrentInstance()
return createVNode(instance.appContext.components[component], props)
} else {
return createVNode(component, props)
}
} catch (err) {
console.error('Unable to create VNode', component, props, err)
}
}
export default {
install(APP) {
APP.$createComponent = createComponent
APP.config.globalProperties.$createComponent = createComponent
}
}
With this plugin, I can now use it for globally registered components like this:
<component :is="$createComponent('my-global-component', { myProp1: 'myValue1', myProp2: 'myValue2' })" />
And for locally imported components:
<component :is="$createComponent(MyComponent, { foo: 'bar' }) />
Alternatively, I can do this within a data method:
data() {
return {
customComponent: $createComponent(MyComponent, { foo: 'bar' })
}
}
<template>
<component :is="customComponent" />
<MyOtherComponent :customizedComponent="customComponent" />
</template>