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