vue3 中如何像 vue2 的 extend 一样挂载未挂载的组件,拿到标签本身($el)

vue3 中如何像 vue2 的 extend 一样挂载未挂载的组件,拿到标签本身($el)

简介:最近在用 vue3 写个新项目,需要挂载自定义的组件,但是发现 vue3 中不再支持 extend 方法了,于是查看了 vant 最新的源码,发现里面有类似实现,特此提炼总结出来。

1.vue2 写法

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
  </head>

  <body>
    <div id="app"></div>
  </body>

  <script>
    // 创建构造器
    const DemoConstructor = Vue.extend({
      render(h, props) {
        return h('div', { style: { fontSize: '24px' } }, '你好' + this.name)
      }
    })
    // 创建 DemoConstructor 实例
    const instance = new DemoConstructor({ data: { name: '小米' } })
    // 手动地挂载一个未挂载的实例。
    instance.$mount()
    console.log(instance.$el)
  </script>
</html>

2.vue3 写法

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://unpkg.com/vue@3.0.2"></script>
  </head>

  <body></body>

  <script>
    const { createApp, h, ref } = Vue
    // vant  源码中是直接用的setup返回的jsx,我这里用的是vue的cdn用法,没有环境支持
    const app = createApp({
      setup(props) {
        const name = ref('小米')
        return { name }
      },
      render() {
        return h('div', { style: { fontSize: '24px' } }, '你好' + this.name)
      }
    })
    // 提供一个父元素
    const parent = document.createElement('div')
    //mount方法不再像vue2一样支持未挂载的实例,必须得挂载,即必须得给参数
    const instance = app.mount(parent)
    console.log(instance)
    console.log(instance.$el)
  </script>
</html>

3.(补充) 在应用之间共享配置

JS用户把里面的类型删除就可以了

import { createApp as createBaseApp, Component } from 'vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { createI18n } from 'vue-i18n'

import Foo from './Foo.vue'
import Bar from './Bar.vue'

const messages = {
  en: {
    message: {
      message1: 'hello world -1',
      message2: 'hello world -2'
    }
  },
  zh: {
    message: {
      message1: '你好,世界 -1',
      message2: '你好,世界 -2'
    }
  }
}

const i18n = createI18n({
  locale: 'en',
  fallbackLocale: 'en',
  messages
})

export const createApp = (options: Component, rootProps?: Record<string, unknown> | null) => {
  const app = createBaseApp(options, rootProps)
  app.use(ElementPlus).use(i18n).use(router).use(store)
  return app
}

const app2 = createApp(Foo).mount('#foo')
const app3 = createApp(Bar).mount('#bar')

参考链接

1.https://github.com/youzan/vant/blob/v3.0.0-beta.10/src/dialog/index.js

2.https://github.com/youzan/vant/blob/v3.0.0-beta.10/src/utils/mount-component.ts

3.https://v3.cn.vuejs.org/guide/migration/global-api.html#%E5%9C%A8%E5%BA%94%E7%94%A8%E4%B9%8B%E9%97%B4%E5%85%B1%E4%BA%AB%E9%85%8D%E7%BD%AE

  • 12
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 30
    评论
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaofei0627

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值