likes
comments
collection
share

vue的冷知识(UI二次封装)前言 不少工程师可能在研发过程中遇到项目选型的UI框架无法满足当前产品的UI需求,如果每次

作者站长头像
站长
· 阅读数 22

前言

不少工程师可能在研发过程中遇到项目选型的UI框架无法满足当前产品的UI需求,如果每次在调用的地方对这些UI做UI的改动是否过于麻烦?其次,部分组件的默认值并不适配于当前系统的配置,每次调用一次组件就需要加一个属性是否也很麻烦?

这个时候有人可能就会说,那我在全局的css文件修改这些样式不可以吗?

答案是当然可以。那如果是部分属性默认值不符合我们的要求呢

下面就引入一种方法,UI框架的部分组件二次封装。(本文仅提供思路,具体如何封装看UI和产品要求)

组件的三要素

用vue开发的猿友们应该都知道,组件有三要素。插槽、属性和方法

我们封装这些组件的时候,需要考虑到如何传递这三要素。

比如:(仅展示关键代码)

// 调用组件test
<test a="1" b="2" @tests="tests">
  <template #testslot>
    <div>1111</div>
  </template>
</test>

组件传递了属性a、b,方法tests以及插槽testslot,我们正常来说接受这三要素的话就是在test组件中声明对应的props、emit以及slot。

那么问题来了,如果我们是对element-ui进行这样的二次封装呢?我们要把每个组件的三要素都一个个的写出来吗?如果后续官方又更新了这三要素呢,我们又要来维护这个二次封装的组件,这样会极大的增加维护成本,那么有没有一种方法可以一劳永逸呢,答案是有的。

属性和方法

属性和方法如何实现透传呢?

以vue3为例,上面的代码示例我们在test组件中打印this可以看到,在this上的$attrs属性上,我们传过去的属性和方法都包含在这个属性里,那么我们在test组件中去接受这些属性和方法是不是就可以用v-bind来绑定$attrs就可以了呢

vue的冷知识(UI二次封装)前言 不少工程师可能在研发过程中遇到项目选型的UI框架无法满足当前产品的UI需求,如果每次 注意:在vue2中2.6+的版本,方法在$listeners中,因此代码可以写成(以el-table为例)

<el-table
    v-bind="$attrs"
    v-on="$listeners" // vue2 2.6+接收方法需要去绑定该属性
>
</el-table>

插槽

属性和方法的透传解决了,那么插槽如何处理呢?

同样的打印this我们可以看到在this的$slots上看到

vue的冷知识(UI二次封装)前言 不少工程师可能在研发过程中遇到项目选型的UI框架无法满足当前产品的UI需求,如果每次 那么,我们可以这样使用:

<el-table
    ref="table"
    v-bind="$attrs"
    v-on="$listeners"
>
    <!-- 透传插槽 -->
    <template v-for="(_, name) in $slots" #[name]="scope">
        <slot :name="name" v-bind="scope"></slot>
    </template>
</el-table>

这样我们就完成了三要素的透传,但是element中有一个东西叫ref,那么这个东西如何实现透传呢?

ref

ref这个是UI框架自定义的东西,我们通过打印el-table的this.$refs.table可以看见,这些方法都挂载在this.$refs.table上,那么我们只需要遍历它的属性并将该属性赋值在当前实例中就可以实现属性的透传。

/**
 * 透传ref属性(该方法在created或者mounted中执行即可)
 */
for (const key in this.$refs.table) {
    this[key] = this.$refs.table[key];
}

这样,我们就实现了对一些UI框架的二次封装。

最后

总结:

// 透传三要素
<el-table
    ref="table"
    v-bind="$attrs"
    v-on="$listeners"
>
    <!-- 透传插槽 -->
    <template v-for="(_, name) in $slots" #[name]="scope">
        <slot :name="name" v-bind="scope"></slot>
    </template>
</el-table>

/**
 * 透传ref属性(该方法在created或者mounted中执行即可)
 */
for (const key in this.$refs.table) {
    this[key] = this.$refs.table[key];
}

如有问题欢迎大家指正,谢谢!

转载自:https://juejin.cn/post/7406147685303255076
评论
请登录