一、二次组件封装原因

组件封装一般是为了提高功能复用性,减少相同功能多次开发的浪费,以及保证项目整体的一致性以及规范性。

因为,在遇到以下情况,我们一般需要进行现有UI组件的二次封装。

  1. 目前UI 组件样式不能满足当前项目要求,需要对组件统一进行样式的封装改造。
  2. 目前UI组件的功能不能满足当前需求,需要对UI组件进行组装,以及功能的改造。

二、问题: 二次封装组件如何继承原有组件的属性、方法及插槽?

1.属性:v-bind="$attrs"

2.方法:v-on="$listeners"

3.插槽: 

 <template
        v-for="(index, name) in $slots"
        :slot="name"
 >
    <slot :name="name" />
 </template>

三、注意事项:

多组件组合封装时,如果组件具有重名的属性、插槽、方法,需要对其单独处理,不然方法可能会相互影响。例如:element-ui的分页与列表都具备方法current-change。

四、示例:封装element-ui 的列表以及分页

1.组件代码:v-table.vue 

<template>
  <div>
    <!-- Table表格 -->
    <el-table
      style="width: 100%"
      v-bind="$attrs"
      v-on="$listeners"
    >
      <template
        v-for="(index, name) in $slots"
        :slot="name"
      >
        <slot :name="name" />
      </template>
    </el-table>
     <!-- /Table表格 -->
    <el-pagination
      v-bind="$attrs"
      v-on="$listeners"
    ></el-pagination>
  </div>
</template>

<script>
export default {
  data () {
    return {}
  },
  created () {},
  methods: {}
}
</script>

2.调用

<template>
  <v-table
    :data=list
    :total=total
    @size-change="handleSizeChange"
    @current-change="handleCurrentChange"
    :current-page=curPage
    :page-sizes="[10, 20, 30, 40]"
    layout="total, sizes, prev, pager, next, jumper"
    :page-size=pageSize
  >
    <el-table-column
      prop="date"
      label="日期"
      width="180"
    ></el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      width="180"
    ></el-table-column>
    <el-table-column
      prop="address"
      label="地址"
    ></el-table-column>
  </v-table>
</template>

<script>
import VTable from './index'
export default {
  components: { VTable },
  data () {
    return {
      curPage: 1,
      list: [],
      total: 100,
      pageSize: 10
    }
  },
  created () {
    this.getData()
  },

  methods: {
    getData () {
      let _this = this
      setTimeout(function () {
         _this.list = []
        for (let i = 1; i <= _this.pageSize; i++) {
          let num = (_this.curPage - 1) * _this.pageSize + i
          let data = {
            date: '2016-05-02',
            name: `王小虎${num}`,
            address: '上海市普陀区金沙江路 1518 弄'
          }
          _this.list.push(data)
        }
      })
    },
    handleSizeChange (val) {
      this.curPage = 1
      this.pageSize = val
      this.getData()
    },
    handleCurrentChange (val) {
      this.curPage = val
      this.getData()
    }
  }
}
</script>

<style>
</style>

3.效果图

Logo

前往低代码交流专区

更多推荐