最近在使用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>
复制代码