最近在使用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拿不到想要的父級,想辦法讓其拿到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,拿到父級的父級也就是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>
複製代碼