使用繼承思想,去開發一款組件(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>
複製代碼
相關文章
相關標籤/搜索