为什么要二次封装UI组件库?
因为业务场景需求现有组件库不满足,需要自己二次封装改造
二次封装UI组件库要考虑哪些东西?
1. UI组件本身的属性以及事件的问题;
2. 组件提供的插槽问题;
UI组件本身的属性以及事件的问题
以Vue3为例,在Vue3中有一个属性名为 $attrs
, $attrs
这个属性是一个对象,它能拿到除了属性定义之外
的,所有的其他传递字段
举🌰
// 子组件
<template>
<div class="customInput">
<el-input placeholder="请输入内容" v-bind="$attrs"></el-input>
</div>
</template>
<script>
export default {
created() {
console.log(this.$attrs)
}
};
</script>
<style scoped>
.customInput{
transition: 0.3s;
}
</style>
// 父组件
<template>
<div class="customInput">
<customInput v-model="val"></customInput>
</div>
</template>
<script setup>
export default {
import customInput from './components/customInput.vue';
const val = ref('')
};
</script>
运行之后看浏览器控制台输出结果:
从控制台可以看出 $attrs
输出结果有两个,一个是 modelValue
, 则一个是事件
,于是第一个问题就通过属性的穿透实现
组件提供的插槽问题
为了避免UI组件库的插槽有不同处理事件,因此我们不能将插槽写死,需要动态生成,也是通过一个属性 $slots
实现;
$slots
打印结果:
通过结果可以看出,$slots
是一个对象,而一个属性带代表父组件传递一个插槽,并且截图发现插槽在JS中本质上也是一个函数,并且一个属性名就是一个插槽的名字
实现方法举个🌰
// 子组件
<template>
<div class="customInput">
<el-input placeholder="请输入内容" v-bind="$attrs">
<template v-for="(value, name) in $slots" #[name]="scopeData">
<slot :name="name" v-bind="scopeData || {}"></slot>
</template>
</el-input>
</div>
</template>
<script>
export default {
created() {
console.log(this.$slots)
}
};
</script>
<style scoped>
.customInput{
transition: 0.3s;
}
</style>
// 父组件
<template>
<div class="customInput">
<customInput v-model="val">
<template #append>
<el-button :icon="Search"></el-button>
</template>
</customInput>
</div>
</template>
<script setup>
export default {
import customInput from './components/customInput.vue';
const val = ref('')
};
</script>
请登录后发表评论
注册
停留在世界边缘,与之惜别