Commit 8fbacfac authored by hcyhuchaoyue's avatar hcyhuchaoyue

fix:提交

parent d207265b
<script setup lang="ts"> <script setup lang="ts">
import { reactive, onMounted } from 'vue'; import { reactive, onMounted } from 'vue';
import { cloneDeep, isEmpty } from 'src/common/utils';
import nestedDraggable from './infra/nested.vue'; import nestedDraggable from './infra/nested.vue';
const state = reactive({ const data = [
list: [] as any[],
});
onMounted(() => {
state.list = [
{ {
name: 'task 1', name: 'task 1',
tasks: [ tasks: [
...@@ -16,6 +12,7 @@ onMounted(() => { ...@@ -16,6 +12,7 @@ onMounted(() => {
tasks: [], tasks: [],
}, },
], ],
key: '1',
}, },
{ {
name: 'task 3', name: 'task 3',
...@@ -25,27 +22,213 @@ onMounted(() => { ...@@ -25,27 +22,213 @@ onMounted(() => {
tasks: [], tasks: [],
}, },
], ],
key: '2',
}, },
{ {
name: 'task 5', name: 'task 5',
tasks: [], tasks: [],
key: '3',
}, },
]; ];
const state = reactive({
list: [] as any[],
originalData: [] as any[],
});
onMounted(() => {
state.originalData = cloneDeep(data);
handleData(data);
state.list = data;
}); });
function handleData(data: any, key = 'tasks', before = 0) {
let index = 0;
data.map((item: any) => {
let indexstr;
if (before) {
indexstr = before + '-' + String(index);
} else {
indexstr = String(index);
}
item['test_index'] = indexstr;
index++;
if (!isEmpty(item[key])) {
handleData(item[key], key, item['test_index']);
} else {
item[key] = [];
}
});
}
function viewData() {
console.log('查看 >>>>', state.list);
}
function onReset() {
const data = cloneDeep(state.originalData);
handleData(data);
state.list = data;
}
// 拖拽结束
function dragEnd() {
handleData(state.list);
console.log('拖拽结束2', state.list);
}
function onAdd() {
let obj: any = {
name: null,
tasks: [],
key: Date.now(),
};
state.list.push(obj);
handleData(state.list);
}
// 删除
function delItem(data: any) {
console.log('删除', data);
data['test_delete'] = true;
let res = handelDel(state.list);
handleData(res);
state.list = res;
}
function handelDel(listdata: any[]) {
const chiledKey = 'tasks';
let newArr = [] as any[];
listdata.map((item) => {
if (!isEmpty(item[chiledKey])) {
item[chiledKey] = handelDel(item[chiledKey]);
}
if (!item['test_delete']) {
newArr.push(item);
}
});
return newArr;
}
// 同级添加
function addItem(data: any) {
console.log('同级添加', data);
const key = 'tasks';
const indexList = data['test_index'].split('-');
let re: any;
for (let i = 0; i < indexList.length; i++) {
const item = indexList[i];
if (i === 0) {
re = getTarget(state.list, Number(item));
} else {
re = getTarget(re.target[key], Number(item));
}
}
let obj: any = {
name: null,
key: Date.now(),
};
obj[key] = [];
re.parent.push(obj);
handleData(state.list);
}
// 子级添加
function addNest(data: any) {
const key = 'tasks';
console.log('子级添加', data);
const indexList = data['test_index'].split('-');
let re: any;
for (let i = 0; i < indexList.length; i++) {
const item = indexList[i];
if (i === 0) {
re = getTarget(state.list, Number(item));
} else {
re = getTarget(re.target[key], Number(item));
}
}
let obj: any = {
name: null,
key: Date.now(),
};
obj[key] = [];
re.target[key].push(obj);
handleData(state.list);
}
function getTarget(list: any, index: number) {
const target = list[index];
const parent = list;
return { target, parent };
}
function getParamData() {
//
let data = cloneDeep(state.list);
let res = delTestKey(data);
console.log('原来的格式', res);
}
function delTestKey(listdata: any[], delKey = 'test_index') {
const chiledKey = 'tasks';
return listdata.map((item: any) => {
if (!isEmpty(item[chiledKey])) {
item[chiledKey] = delTestKey(item[chiledKey], delKey);
}
delete item[delKey];
return item;
});
}
</script> </script>
<template> <template>
<div class="box"> <div class="box">
<div class="actions">
<q-btn color="primary" label="查看" @click="viewData" />
<q-btn color="primary" label="原来的格式" @click="getParamData" />
<q-btn color="primary" label="重置" @click="onReset" />
<q-btn color="primary" label="添加" @click="onAdd" />
</div>
<div class="tree-box"> <div class="tree-box">
<h3>标题</h3> <nested-draggable
<nested-draggable :tasks="state.list" /> :tasks="state.list"
@onEnd="dragEnd"
@addItem="addItem"
@addNest="addNest"
@delItem="delItem"
/>
</div> </div>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.actions {
padding: 10px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
column-gap: 10px;
}
.tree-box { .tree-box {
width: 600px; width: 600px;
height: 500px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid brown; border: 1px solid brown;
overflow: auto;
> :nth-child(1) {
padding-right: 10px;
}
} }
</style> </style>
<template>
<div class="row">
<div class="col-1">
<button class="btn btn-secondary button" @click="add">Add</button>
</div>
<div class="col-7">
<h3>Draggable {{ draggingInfo }}</h3>
<draggable
tag="ul"
:list="list"
class="list-group"
handle=".handle"
item-key="name"
>
<template #item="{ element, index }">
<li class="list-group-item">
<i class="fa fa-align-justify handle"></i>
<span class="text">{{ element.name }} </span>
<input type="text" class="form-control" v-model="element.text" />
<i class="fa fa-times close" @click="removeAt(index)"></i>
</li>
</template>
</draggable>
</div>
<rawDisplayer class="col-3" :value="list" title="List" />
</div>
</template>
<script>
let id = 3;
import draggable from 'vuedraggable';
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'handle',
display: 'Handle',
instruction: 'Drag using the handle icon',
order: 5,
components: {
draggable,
},
data() {
return {
list: [
{ name: 'John', text: '', id: 0 },
{ name: 'Joao', text: '', id: 1 },
{ name: 'Jean', text: '', id: 2 },
],
dragging: false,
};
},
computed: {
draggingInfo() {
return this.dragging ? 'under drag' : '';
},
},
methods: {
removeAt(idx) {
this.list.splice(idx, 1);
},
add: function () {
id++;
this.list.push({ name: 'Juan ' + id, id, text: '' });
},
},
};
</script>
<style scoped>
.button {
margin-top: 35px;
}
.handle {
float: left;
padding-top: 8px;
padding-bottom: 8px;
}
.close {
float: right;
padding-top: 8px;
padding-bottom: 8px;
}
input {
display: inline-block;
width: 50%;
}
.text {
margin: 20px;
}
</style>
<template> <template>
<draggable <draggable
class="dragArea" class="drag-area"
tag="ul" tag="div"
:list="tasks" :list="tasks"
handle=".handle"
:group="{ name: 'g1' }" :group="{ name: 'g1' }"
item-key="name" item-key="key"
:onEnd="onEnd"
:animation="150"
> >
<template #item="{ element }"> <template #item="{ element }">
<li> <div class="drag-area-item">
<p>{{ element.name }}</p> <div class="drag-area-item-conten">
<nested-draggable :tasks="element.tasks" /> <!-- <div class="text">{{ element.name }}</div> -->
</li> <div>
<i class="fa fa-align-justify handle"></i>
<input type="text" class="form-control" v-model="element.name" />
</div>
<div class="actions">
<q-btn color="primary" icon="bi-list" @click="addItem(element)" />
<q-btn
color="primary"
icon="bi-list-nested"
@click="addNest(element)"
/>
<q-btn color="primary" label="删除" @click="delItem(element)" />
</div>
</div>
<nested-draggable
:tasks="element.tasks"
@onEnd="onEnd"
@addItem="addItem"
@addNest="addNest"
@delItem="delItem"
/>
</div>
</template> </template>
</draggable> </draggable>
</template> </template>
<script> <script>
import { isEmpty } from 'src/common/utils';
import draggable from 'vuedraggable'; import draggable from 'vuedraggable';
export default { export default {
name: 'nested-draggable',
props: { props: {
tasks: { tasks: {
required: true, required: true,
...@@ -26,14 +52,73 @@ export default { ...@@ -26,14 +52,73 @@ export default {
components: { components: {
draggable, draggable,
}, },
name: 'nested-draggable',
setup(props, ctx) {
const addItem = (data) => {
ctx.emit('addItem', data);
};
const addNest = (data) => {
ctx.emit('addNest', data);
};
const delItem = (data) => {
ctx.emit('delItem', data);
};
// 拖拽结束
const onEnd = (data) => {
ctx.emit('onEnd', data);
};
return {
isEmpty,
addItem,
addNest,
delItem,
onEnd,
};
},
}; };
</script> </script>
<style scoped> <style scoped lang="scss">
.dragArea { .drag-area {
min-height: 50px; min-width: 450px;
// min-height: 20px;
overflow: auto;
/* outline: 1px dashed; */ /* outline: 1px dashed; */
border: 1px solid red; border: 1px solid red;
padding-left: 40px;
& > :nth-child(1) {
margin-top: 10px;
}
.drag-area-item {
min-width: 450px;
outline: 1px solid #1ee3cf;
margin-bottom: 10px;
.drag-area-item-conten {
height: 40px;
box-sizing: border-box;
background-color: #f9bcdd;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
.actions {
padding: 10px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
column-gap: 10px;
}
}
}
.handle {
float: left;
padding: 8px;
}
} }
</style> </style>
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment