当前位置: 首页>编程语言>正文

vue基于 inheritAttrs进行组件二次封装

曾经,我在封装ui库的组件时都是这样的:


vue基于 inheritAttrs进行组件二次封装,第1张
element的table组件,冗长的自定义属性

然后为了能够使代码更简洁,同时能在父组件随意传入自定义的属性,我设想过使用jsx,因为我见过公司有react项目,里面使用了扩展运算符来传入元素的属性,可惜当时试了一下在vue的render里面这么用结果失败了。直到今天我在浏览文章的时候偶然发现了一个在vue里面我从未使用过的知识点:inheritAttrs,官方文档上是这样介绍的:
如果你不希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false...这尤其适合配合实例的$attrsproperty使用,该 property 包含了传递给一个组件的 attribute 名和 attribute 值,有了 inheritAttrs: false$attrs,你就可以手动决定这些 attribute 会被赋予哪个元素。

之后我查阅资料发现简单来说就是通过设置inheritAttrs: false使得最终的html元素不会继承父组件传入的属性,然后再给子组件设置v-bind直接绑定父组件传入的属性,这样就可以做到父组件的属性直接绑定到ui库组件上,而不需要在子组件中周转一下,另外在子组件上使用v-on="$listeners"也可以将ui组件的事件直接传入父组件,这样一来二去代码可以说是简洁多了。

附上基于iview二次封装的table组件的基础代码

<template>
  <Table
    :data="data"
    :loading="status.loading"
    v-bind="customAttrs"
    v-on="$listeners"
  >
  </Table>
</template>

<script>
export default {
  name: 'BaseTable',
  inheritAttrs: false,
  props: {
    data: {
      type: Array,
      default: () => []
    },
    // table的props 以及其它自定义属性
    config: {
      type: Object,
      default: () => {
        return {
          tableProps: {}, // iview-table的属性放入此对象(剔除了data和一些状态属性如loading)
        };
      }
    },
    status: {
      type: Object,
      default: () => {
        return {
          loading: false
        };
      }
    }
  },
  data() {
    return {
    };
  },
  computed: {
    // 获取从父组件直接传入iview的属性
    customAttrs() {
      return {
        ...this.config.tableProps
      };
    },
  },
};
</script>

父组件调用这个组件之后只需在config.tableProps中按照ui库的文档写上自己的属性即可,另外我将loading状态和data单独抽离便于管理,然后ui组件的事件直接在父组件上监听就行。

之后我在此封装的基础上又过滤出了自定义列模板的项并进行处理,完整代码见
https://github.com/dwtom/vue2x-playground
其中的views/iview/TableComponent就是了。

参考内容

vue官网
一个透传技巧,治好了我的重度代码洁癖


https://www.xamrdz.com/lan/55p1993977.html

相关文章: