1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 用elemet-ui组件实现弹窗里的树形结构和拖拽功能

用elemet-ui组件实现弹窗里的树形结构和拖拽功能

时间:2021-02-05 22:21:16

相关推荐

用elemet-ui组件实现弹窗里的树形结构和拖拽功能

这个弹窗功能,主要是导出字段的设置,左边是树形字段结构,右边是选中的设置字段,字段可以拖动调顺序。我实现这个功能主要用的element-ui里的tree和dialog组件,及vuedraggable组件,如果没有拖拽功能差不多半个小时就搞定这个功能,就因为实现这个拖拽功能,浪费了很多时间,从昨天晚上八点多开始,一直折腾到十一点多,大致效果如图

刚开始没考虑到拖拽会引起这么多问题,只是用store,state选中的字段,和选中的id给存起来,这样可以实现公用,及后面的设置存储数据

模拟数据如下

data2: [{id: 1,label: '一级 1',children: [{id: 4,label: '二级 1-1',children: [{id: 9,label: '三级 1-1-1'}, {id: 10,label: '三级 1-1-2'}]}]}, {id: 2,label: '一级 2',children: [{id: 5,label: '二级 2-1'}, {id: 6,label: '二级 2-2'}]}, {id: 3,label: '一级 3',children: [{id: 7,label: '二级 3-1'}, {id: 8,label: '二级 3-2'}]}]

import Service from './service'import config from './config'const store = {namespaced: true,state: {checkedFields: [], //选中对象fieldKeys: [], //选中的iddeepData: []},mutations: {setCheckedFields (state, data = []) {state.checkedFields = data},setFieldKeys (state, keys = []) {state.fieldKeys = keys},setDeepData (state, data = []) {state.deepData = data}}}export default store

后来发现在这个行不通,数据都是共用的,拖动,删除的实话容易造成排序问题,

后来就把选中的给深拷贝来一份,左右数据相当独立,在state中添加了一个变量,

deepData: []

mutations: {setCheckedFields (state, data = []) {state.checkedFields = data},setFieldKeys (state, keys = []) {state.fieldKeys = keys},setDeepData (state, data = []) {state.deepData = data}}

利用getters处理数据获取深拷贝后的id数据,如下

getters: {deepKeys (state) {const { deepData } = statelet arr = []deepData.map(ele => {arr.push(ele.id)})return arr}}

然后监听tree里面的复选框事件,再递归循环数据,对比是选中还是重置,然后再根据情况,修改deepData里的值,刚开始用的tree里的check-change事件,发现这个事件容易触发几次事件,如果在父节点上点击,这样就获取了重复数据,右边的数据也出现了重复现象,后来用check事件避免了这个问题

实现代码如下

//监听事件方法handleCheckChange (data, checked) {let isReset = checked.checkedKeys.every(ele => ele !== data.id)if (!isReset) {this.$refs.tree.store.nodesMap[data.id].expanded = truedata.unfold = truethis.dataCheck(data, !isReset)} else {this.dataCheck(data, !isReset)}this.setCheckedFields(this.$refs.tree.getCheckedNodes(true))this.setFieldKeys(this.$refs.tree.getCheckedKeys(true))},dataCheck (obj, b) {let arr = []this.dataLoop(obj, arr)if (b) {this.setDeepData(cloneDeep(this.deepData.concat(arr)))} else {arr.forEach(ele => {this.deepData.forEach(val => {if (ele.id === val.id) {this.deepData.splice(this.deepData.indexOf(val), 1)this.setDeepData(cloneDeep(this.deepData))}})})}},//递归dataLoop (obj, arr) {let arr2 = obj.childrenif (arr2) {arr2.forEach(ele => {this.dataLoop(ele, arr)})} else {arr.push(obj)}}

删除功能是利用watch监听deepKeys变化,然后再设置

删除功能代码:

delItem (index) {this.deepData.splice(index, 1)}

watch监听deepKeys变化

watch: {deepKeys (newkeys) {if (newkeys) {this.$refs.tree.setCheckedKeys(newkeys, true)}}},

拖拽功能实现主要用的vuedraggable组件,实现代码如下:

<draggable:list="child"@end="dragEndHandle"><liv-for="(item, index) in child":key="item.id":index1="item.index"><span>{{ item.label }}</span><div class="set-field-tool"><iclass="icon iconfont icon-move"/><iclass="icon iconfont icon-minus"@click="delItem(index)"/></div></li></draggable>

拖拽js代码如下:

dragEndHandle ({ oldIndex, newIndex }) {const { deepData } = thisconst item = deepData[oldIndex]deepData.splice(oldIndex, 1)deepData.splice(newIndex, 0, item)}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。