vue3 中说 createApp
只能调用一次,可是我现在有两个场景需要手动挂载 组件的情况:
场景一
手动挂载弹窗,比如我手动挂载一个按钮组件:
const SubVue = Vue.extend(Button)
const ButtonInstance = new SubVue({
propsData: {
type: 'primary'
},
})
ButtonInstance.$slots = {
default: 'el-button',
}
ButtonInstance.$mount(this.$refs.container)
vue3 中不再支持 extend
, 因此我使用createApp
代替,可是第二次调用createApp
的返回值和第一次调用的返回值不同,第二次的返回值没有umount
方法,挂载后无法手动卸载应用。
场景二
有你一个表格,我使用render
函数自定义列内容,比如:
{
label: '调查情况',
// prop: 'iis',
prop: ({ row }) => {
const item = planOptions.find(item => item.value === row.iis)
return <span>{item?.label ?? ''}</span>
},
},
prop 传递一个 render 函数,实现列自定义。
前端在导出当前页数据的时候,为了能拿到 render 函数渲染后的数据,我就手动调用 careateApp 手动渲染 vNode, 然后获取 textContent, 在使用 textContent 填充表格,去导出,目的是为了拿到映射后的结果,用户能理解。
关键代码:
const vNode = item.prop({ row })
console.log(vNode)
// eslint-disable-next-line vue/one-component-per-file
const rowApp = createApp({
render() {
return h(vNode)
},
}).mount('#temp-row')
value = el.textContent
rowObj[item.label] = value
console.log(rowApp)
// rowApp.unmount() // rowApp 没有 umount 方法,无法卸载
为何我手动挂载 render 函数?
我想要拿到最后渲染输出,再导出到 excel 表格中,比如 接口返回 1 表示成功,表格的某一列需要显示成功,为了映射关系因包含在表格的自定义列的 render 函数里,我手动得挂载 render, 再去获取渲染后的 textContent , 就是用户能理解的数据,而不是 1.
rowApp 没有 umount 方法,无法卸载这个零时的 app, 使用 vue 的开发工具查看,能看到很多 App。
问题总结,一个 vue3 应用中无法多次调用createApp
,比如这样:
const app: App = createApp(App) // 一个任意组件
console.log('app')
console.log(app)
const rowApp = createApp({
setup(){
return ()=>h('p','row-app')
}
}).mount('#temp-row')
console.log('rowApp')
console.log(rowApp)
两次调用的返回值不同,第二次调用无法卸载 rowApp。
如何多次调用 createApp 或者如何变相实现我这两个需求?
破案了,我的思路是对的,是createApp 调用方式不对。
正确的调用方式:
这样调用是错误,返回是 mount 的, 没有 unmout 方法