使用继承思想,去开发一款组件(element-ui collapse组件为例子)

最近在使用element-ui collapse组件的过程当中,须要用collapse-item实现拖拽排序,本来组件知足不了,先看下组件的原形。(本文使用的element-ui是用1.4.2版本)vue

初版

拖拽结合开源组件 vuedraggable,详细查看vuedraggable组件的用法。node

<el-collapse>
  <draggable v-model="arr">
    <el-collapse-item v-for="(item, index) in arr" :key="'key-' + index">
      <template slot="title">
        <span>{{'collapse-item-' + item}}</span>
      </template>
    </el-collapse-item>
  </draggable>
</el-collapse>
复制代码

而后就报错了,呼~ 报错在于,collapse-item组件。 npm

经过阅读element-ui,collapse-item源码路径在 node_modules_element-ui@1.4.2@element-ui\packages\collapse\src\collapse-item.vueelement-ui

computed: {
  isActive() {
    return this.$parent.activeNames.indexOf(this.name) > -1;
  }
},
复制代码

能够看到计算属性isActive经过父级activeNames来定义的,然而如今组件的层级结构是这样。bash

collapse-item的父级是draggable, 确定拿不到本来collapse的父级。

第二版

既然collapse-item拿不到想要的父级,想办法让其拿到collapse,组件重写的思想,能够查看笔者的另一问: 开发VUE使用第三库,发现有bug怎么办?,固然这里不是组件存在bug,而是扩展,思路是同样的。post

建立weCollapseIten.vue组件ui

<script>
import {
  CollapseItem
} from 'element-ui'
export default {
  // 继承了CollapseItem
  extends: CollapseItem,
  computed: {
    isActive () {
      // 这里重写
      return this.$parent.$parent.activeNames.indexOf(this.name) > -1
    }
  }
}
</script>
复制代码

经过this.parent.parent,拿到父级的父级也就是collapse了。this

<el-collapse>
  <draggable v-model="arr">
    // 使用新组件
    <we-collapse-item v-for="(item, index) in arr" :key="'key-' + index">
      <template slot="title">
        <span>{{'collapse-item-' + item}}</span>
      </template>
    </we-collapse-item>
  </draggable>
</el-collapse>
复制代码

大功靠成,功能已经实现。等等,这样是否还不够通用,并且在element-ui组件之间嵌套一个新的组件,对于阅读者来讲确定是一脸懵逼。不够通用并且没有能够读性。spa

第三版

建立weCollapse.vue组件.net

// 将element-ui collapse组件的模板重写
<template>
  <draggable 
    class="el-collapse"
    :list="list""> <slot></slot> </draggable> </template> <script> import draggable from './vuedraggable' import { Collapse } from 'element-ui' export default { // 重写collapse组件 extends: Collapse, props: { list: Array }, components: { draggable } } </script> 复制代码

本来是这样,使用draggable这件代替div,引用weCollapse组件就已经嵌入了draggable组件,带有拖拽的功能,同时不影响本来element-ui collapse组件的功能。

<template>
  <div class="el-collapse">
    <slot></slot>
  </div>
</template>
复制代码

最终,代码使用组件以下,跟element-ui本来组件的引用的同样的,而功能上却已经大不相同,这样的好处就不少了,固然这组件编写还不完美,wecollapse是否能够支持拖拽应该是封装成一个属性,不支持拖拽的就不须要用draggable来作包裹了,还有自己draggable支持的属性也应该wecollapse来作支持。

<we-collapse :list="arr">
  <we-collapse-item v-for="(item, index) in arr" :key="'key-' + index">
    <template slot="title">
      <span>{{'collapse-item-' + item}}</span>
    </template>
  </we-collapse-item>
</we-collapse>
复制代码
相关文章
相关标签/搜索