开发兼容vue2和vue3的组件
钢翼
编程
网上很多尬吹vue-demi的,很怀疑是否真的用过,这玩意用起来限制还是蛮多的。
我觉得vue-demi原理可能就是api的重定向(没深入源码研究)。
所以你在vue3用的setup等语法在vue2中由于是没有的,你是不能用的。
vue-demi能兼容的主要原因是vue3有历史包袱,保留了大部分vue2的api。
所以我们不用vue-demi也可以开发兼容vue2和vue3的组件。 目标是一套代码一个包,同时兼容vue2和vue3。需要注意的是我们得用vue2的写法来写组件。还有不能用sfc,即template。 vue2的话需要升级到vue2.7以上版本。
步骤
1.使用vue3编写组件
基本就是改成vue2的写法,然后模板改为rander的h函数或jsx进行渲染,下面是h函数的写法
//xx.ts
import { h as h1, defineComponent } from 'vue';
import * as Vue from 'vue'
import config from '../../package.json'
export default defineComponent({
name: "GeEcharts",
version: config.version,
props: {
height: {
type: [String, Number],
require: false,
default: 400
},
content:{
type: String
}
},
data() {
return {
chartHeight: this.height,
}
},
mounted() {
},
methods: {
},
render(createElement:any) {
const isVue2 = Vue.version.split('.')[0] == '2'
//vue2 和vue3的v-html写法不太一样,需要区分
if (isVue2) {
//vue2
const h = createElement
return h('div', {
domProps: {
innerHTML: this.content
},
style: {
height: this.chartHeight + 'px'
}
})
}else{
//vue3
const h = h1
return h('div', {
innerHTML: this.content,
style: {
height: this.chartHeight + 'px'
}
})
}
}
})
2.使用jsx
引用
npm install -D @vitejs/plugin-vue-jsx
# 或
yarn add -D @vitejs/plugin-vue-jsx
修改vite.config.ts
import vue from '@vitejs/plugin-vue'
import dts from 'vite-plugin-dts'
+import vueJsx from '@vitejs/plugin-vue-jsx'
export default defineConfig({
plugins: [vue(),
+ vueJsx({ pragma:"h"}), //将createVNode改为h,在render中必须给h赋值。
dts({include:['src/index.ts']
})],
optimizeDeps: {
exclude: ["vue-demi"],
},
build: {
lib: {
entry: './src/index.ts',
formats: ['es', 'umd'],
name: 'GeUI',
fileName: (format) => `index.${format}.js`
},
rollupOptions: {
external: ['vue'],
output: {
globals: {
vue: 'Vue'
}
}
}
}
})
组件后缀从ts改为tsx。render改成jsx语法
//xx.tsx
render(createElement:any) {
//下面给h赋值,是由于h函数在vue2和vue3中不一致。
const isVue2 = Vue.version.split('.')[0] == '2'
const h = isVue2 ? createElement : Vue.createVNode
//domProps是vue2的v-html写法 innerHTML是vue3的v-html写法,两个都写即可兼容
return (<div style={{ height: this.chartHeight + 'px' }} innerHTML={this.content} domProps={{ innerHTML: this.content }}></div>)
}
总结:用习惯template,改用h函数和jsx还是不太方便。在h函数和jsx之间,推荐还是选jsx吧。至少比h函数容易维护。
参考:https://blog.csdn.net/ambit_tsai/article/details/104628676