Vue 3:将组件挂载到现有的应用示例上

6za6bjd0  于 2023-06-24  发布在  Vue.js
关注(0)|答案(1)|浏览(252)

我有一个用Vue 2编写的插件,它可以编程方式将组件挂载到现有的应用示例上。

export default {
  install (Vue) {
    const component = new (Vue.extend(Component))()
    const vm = component.$mount()
    document.body.appendChild(vm.$el)
  }
}

尝试将其迁移到Vue 3,这是我最接近的。

export default {
  install (app) {
    const component = defineComponent(Component)
    const container = document.createElement('div')
    document.body.appendChild(container)
    const vm = createApp(component).mount(container)
  }
}

问题是createApp创建了一个新的应用示例,而Vue.extend只创建了一个子类。我需要有在主应用程序中的所有全球可用组件,在插件的组件以及可用。创建新的应用示例可以防止这种情况。
组件需要以编程方式装入。手动将其插入到模板中不是一个选项。
请帮帮我

mqkwyuun

mqkwyuun1#

有趣的问题!有一个discussion on the Vue GitHub,他们创建了一个模块,你可以用途:mount-vue-component.我发现看the module's code很有帮助,它确实做了你想做的事情。
要示例化该组件,必须创建一个VNode,可以使用createVNode()(与h()相同)来执行此操作。要访问应用的上下文(包括全局组件),必须设置appContext属性。最后,render()函数将组件示例挂载到HTML元素。
举个例子,这给了你:

export default {
  install (app) {
    const container = document.createElement('div')
    document.body.appendChild(container)

    const vNode = createVNode(component)
    vNode.appContext = app._context
    render(vNode, container)
  }
}

下面是一个片段:

const { createApp, createVNode, ref, render  } = Vue;

const App = {
  data() {
    return {
      msg: ref('Hello from app!')
    }  
  }
}
const app = createApp(App)

app.component('inner-component', {
  template:  '<div style="color: green;">This is a global component in app</div>'
})
app.mount('#app')

const component = {
  props: ['color'],
  template: '<span :style="{color: color}">Hello from mounted component!</span><inner-component></inner-component>'
}
const el = document.getElementById('leComponent')
const vNode = createVNode(component, {color: 'blue'}, [])
vNode.appContext = app._context
render(vNode, el)
div{
  margin: 4px;
  padding: 4px;
  border: 1px solid #333;
}
<div id="app">
  {{msg}}
  <inner-component></inner-component>
</div>
<div id="leComponent"></div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

相关问题