网站如何做微信分享推广,分销平台搭建,安装wordpress导入工具栏,青岛做网站建设的公司1. 组件特性
在Vue中组件是一个独立的实例#xff0c;每个组件都有共通点#xff0c;就是#xff1a;属性、插槽、事件、方法#xff1b;
在日常我们使用第三方组件库的时候#xff0c;组件库的文档都会说明上面四个特性#xff0c;而组件封装就是围绕这四个特性进行的…1. 组件特性
在Vue中组件是一个独立的实例每个组件都有共通点就是属性、插槽、事件、方法
在日常我们使用第三方组件库的时候组件库的文档都会说明上面四个特性而组件封装就是围绕这四个特性进行的
2. 组件封装
2.1 组件继承
很多情况下我们会在一个组件的基础上进行扩展这个时候就需要用到组件继承
在Vue2的时候我们可以使用extends关键字进行组件继承但是在Vue3中extends关键字已经被废弃了
在Vue3中如果想要实现组件继承其实很简单要明白一个组件其实就是一个js对象我们可以直接将一个组件对象合并然后注册成一个新的组件
import { createApp } from vue;
import App from ./App.vue;
import ElementPlus, { ElInput } from element-plus;
import element-plus/dist/index.css;
import { merge } from lodash;const app createApp(App);
app.use(ElementPlus);// 组件继承将ElInput组件的placeholder属性默认值改为请输入
app.component(ElInput,merge(ElInput, {props: {placeholder: {default: 请输入}}})
);app.mount(#app);这里直接使用了lodash的merge方法将ElInput组件的props属性进行了合并然后覆盖注册成了一个新的组件
因为有很多小伙伴遇到一个问题就是需要固定ElTable组件的一些属性比如border、stripe、size等这个时候用这种方法就非常方便
2.2 组件插槽
上面的组件继承只是简单的改变了组件的默认属性但是如果我们想要改变组件的结构就需要用到组件插槽
通常情况下我们要拆分组件的业务然后封装成业务组件这个时候可能会使用到多个组件
这个时候组件里面有很多组件需要替换组件里面的组件里面的插槽这个时候就需要透传插槽
!-- 透传插槽 --
templatediv区域A这里有一个组件这个组件需要替换插槽el-tree :datatreeDatatemplate v-if$slots.tree #default{ node, data }slot nametree :nodenode :datadata //template/el-tree/divdiv区域B这里有一个组件这个组件需要替换插槽el-table :datatableDatatemplate v-if$slots.defaultslot //template/el-table/div
/templatescript
export default {data() {return {treeData: new Array(10).fill(0).map((_, index) ({ label: label index })),tableData: [],};},
};
/script通过使用$slots可以获取到组件的插槽然后通过v-if判断是否有插槽如果有插槽就进行透传
除了这种方式之外还可以使用jsx语法这种方式更加灵活
script langjsx
export default {render() {const areaA (div区域A这里有一个组件这个组件需要替换插槽el-tree data{treeData}{{default: this.$slots.tree}}/el-tree/div);const areaB (div区域B这里有一个组件这个组件需要替换插槽el-table data{tableData}{{default: this.$slots.default}}/el-table/div);return (div{areaA}{areaB}/div);}
}
/script在setup语法中是没有this的这个使用需要获取$slots的时候需要使用useSlots方法 2.3 组件事件和透传 attrs
在Vue2中我们可以使用$listeners来获取组件的事件然后进行透传
而在Vue3中$listeners已经被废弃了$listeners和$attrs都被合并到了$attrs中
!-- 组件 --
templatediv v-bind$attrs/div
/template!-- 父组件 --
templatedivMyComponent classmy-classclickhandleClick//div
/template在Vue3中我们可以直接使用$attrs来获取组件的事件然后进行透传
例如上面的例子我们可以直接在组件中使用$attrs来获取到class和click事件等同于下面的写法
!-- 组件 --
templatediv classmy-class clickhandleClick/div
/template但是这里其实有一个小技巧就是Vue3默认属性是可以透传的例如上面的例子其实可以简化成下面的写法
!-- 组件 --
templatediv/div
/template!-- 父组件 --
templatedivMyComponent classmy-classclickhandleClick//div
/template就是组件里面什么都不写最后在父组件中使用这个组件的时候属性会透传到组件中的根元素上
参考透传 Attributes[1]
了解这个特性就可以这样封装组件
!-- 组件 --
templateel-dialog/el-dialog
/template!-- 父组件 --
templatedivMyComponent v-modelvisiblewidth500px//div
/template通常我们会封装一个Dialog组件来解耦业务这个时候直接将Dialog作为根元素然后可以将v-model和width属性透传到Dialog组件上
这样不需要写Dialog组件开启关闭的双向绑定的代码前提是不需要在组件内部操作Dialog的开启关闭
2.4 组件方法
在Vue2中我们可以通过this.$refs.xxx来获取到组件的实例然后调用组件的方法
在Vue3中我们可以通过ref来获取到组件的实例然后调用组件的方法
但是不管是Vue2还是Vue3在组件内部想要使用组件的子组件的方法都不是一件容易的事情
通常都是手动将组件的实例获取到然后再重新定义在组件的methods中
!-- 组件 --
templatedivel-input refinput //div
/templatescript
export default {methods: {focus() {this.$refs.input.focus();},},
};
/script组件的方法通常没有啥特别好的方式除了我上面的这种方式之外还有小伙伴是直接将ref返回出去
templatedivel-input refinput //div
/templatescript
export default {methods: {inputRef() {return this.$refs.input},},
};
/script当然还有一种偷懒的方式
templatedivel-input refinput //div
/templatescript
export default {mounted() {Object.values(this.$refs.input).forEach((value) {if (typeof value function) {this[value.name] (...args) value(...args);}});},methods: {inputRef() {return this.$refs.input},},
};
/script不过这种偷懒的方式只能在options api中使用因为在composition api中是没有this的
对于setup语法如果需要使用组件的方法可以使用getCurrentInstance来获取到组件的实例然后将方法挂载到exposed上
templatedivel-input refinput //div
/templatescript setup
import { getCurrentInstance, onMounted, ref } from vue;const instance getCurrentInstance();
const input ref(null);
onMounted(() {Object.values(input.value).forEach((value) {if (typeof value function) {instance.exposed[value.name] (...args) value(...args);}});
});
/script这种方式不太稳定因为exposed是Vue3的一个私有属性不建议使用 在setup语法中如果需要暴露组件的内部方法需要使用defineExpose来暴露 script setup
// ... 省略其他代码defineExpose({focus: () {input.value.focus();},
});
/script总结
这次的是Vue3的组件封装的一些技巧主要是setup语法的一些特性以及Vue3中的一些技巧