Subscribe on changes!

Is Vue3 support install plugin without instance?(在Vue3中不实例化 app 安装插件的方法?)

avatar
Jul 6th 2022

What problem does this feature solve?

We have a plugin that help us create instance in suitable time,Instead of in main.js。Therefore, we pass "createInstance" method to the plugin, which will call it。In Vue2 we use like that,it work fine:

我们有个插件用来帮助我们在合适的时间创建 vue 实例,而不是在 main.js 中立即创建,因此我们把 Vue 的实例构造方法传递给插件,由它进行调用。在Vue2 中我们是这样使用的:

import Plugin from 'aviana-plugin-vue'
Vue.use(Plugin, {
  ...config,
  createInstance: (container, router) => {
    return new Vue({
      router: router,
      store: store,
      render: h => h(App),
    }).$mount(container ? container.querySelector('#app') : '#app')
  },
})

But in Vue3,We must use the Instance to install Plugin,just like: 但在 Vue3 中,我们必须先创建 Vue 实例再安装插件:

const app = createApp(App) // we need app.use(),but app instance shouldn't be create here
app.use(Plugin, {
  ...config,
  createInstance: (container: any, router: any) => {
    // it is not work because "app" is already created
    app.use(store)
    app.use(router)
    app.mount(container ? container.querySelector('#app') : '#app')
    return app
  },
})

Is there any solution? Thanks!

What does the proposed API look like?

import { SomethingLikeVue } from 'vue'
SomethingLikeVue.use(Plugin, {
  ...config,
  createInstance: (container, router) => {
    const app = createApp(App)
    app.use(store)
    app.use(router)
    app.mount(container ? container.querySelector('#app') : '#app')
    return app
  },
})
avatar
Jul 6th 2022

Vue3的插件是针对实例的,你这个插件所实现的功能更像一个函数做的事情吧 const app = Plugin(config) ;

avatar
Jul 6th 2022

Vue3的插件是针对实例的,你这个插件所实现的功能更像一个函数做的事情吧 const app = Plugin(config) ;

Vue2 的时候用 install 是因为同时有很多 原型链挂载、Mixin 的动作要做。现在 Vue3 的话插件得在实例构造方法被调用后,再对 app 做相关操作,逻辑上差别较大。目前想在一个插件内把 Vue2 和 Vue3 统一兼容起来,实现上没问题,就是看怎么写比较优雅。

avatar
Jul 6th 2022

为了同时支持 Vue2 和 Vue3,我改成了这样(xxx-plugin 中没有依赖 vue 库):

Vue2:

import { install } from 'xxx-plugin'
install(
  {
    ...config,
    createInstance: (container, router) => {
      return new Vue({
        router: router,
        store: store,
        render: h => h(App),
      }).$mount(container ? container.querySelector('#app') : '#app')
    },
  },
  Vue,  // 为了挂载原型链和 Minxin
)

Vue3:

import { install } from 'xxx-plugin'
install(
  {
    ...config,
    createInstance: (container, router) => {
      const app = createApp(App)
      app.use(store)
      app.use(router)
      app.mount(container ? container.querySelector('#app') : '#app')
      return app
    },
  }
)

感觉在 Vue2 中 install 方法传递的这个 Vue 很别扭,有其他好点子吗?

avatar
Jul 11th 2022

试了下通过实例也能进行 Minxin 和 原型链挂载,Issue Close