|
@@ -1,19 +1,14 @@
|
|
<template>
|
|
<template>
|
|
<div class="vtl-node" :id="model.id" :class="{ 'vtl-leaf-node': !isFolder, 'vtl-tree-node': isFolder }">
|
|
<div class="vtl-node" :id="model.id" :class="{ 'vtl-leaf-node': !isFolder, 'vtl-tree-node': isFolder }">
|
|
- <div
|
|
|
|
- :class="treeNodeClass"
|
|
|
|
- @mouseover="mouseOver"
|
|
|
|
- @mouseout="mouseOut"
|
|
|
|
- @click.stop="toggle"
|
|
|
|
- >
|
|
|
|
|
|
+ <div :class="treeNodeClass" @mouseover="mouseOver" @mouseout="mouseOut" @click.stop="toggle">
|
|
<div class="vtl-border-text">
|
|
<div class="vtl-border-text">
|
|
<template v-if="isFolder">
|
|
<template v-if="isFolder">
|
|
<slot v-if="expanded" :item="{ title: model.title, isFolder: true, expanded: true }" name="icon"> </slot>
|
|
<slot v-if="expanded" :item="{ title: model.title, isFolder: true, expanded: true }" name="icon"> </slot>
|
|
<slot v-else :item="{ title: model.title, isFolder: true, expanded: false }" name="icon"></slot>
|
|
<slot v-else :item="{ title: model.title, isFolder: true, expanded: false }" name="icon"></slot>
|
|
-
|
|
|
|
|
|
+
|
|
</template>
|
|
</template>
|
|
<slot v-else :item="{ title: model.title, isFolder: false }" name="icon"></slot>
|
|
<slot v-else :item="{ title: model.title, isFolder: false }" name="icon"></slot>
|
|
- <span class="vtl-node-content ellipsis" >
|
|
|
|
|
|
+ <span class="vtl-node-content ellipsis">
|
|
{{ model.title }}
|
|
{{ model.title }}
|
|
</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
@@ -26,14 +21,8 @@
|
|
</div>
|
|
</div>
|
|
<div class="vtl-tree-margin" v-show="expanded">
|
|
<div class="vtl-tree-margin" v-show="expanded">
|
|
<!-- 这里无法使用$attr来透传属性官方还未解决此bug -->
|
|
<!-- 这里无法使用$attr来透传属性官方还未解决此bug -->
|
|
- <treeList
|
|
|
|
- @on-click="(depth) => $emit('onClick', depth)"
|
|
|
|
- @detail-node="(depth) => $emit('detailNode', depth)"
|
|
|
|
- v-for="newmodel in model.children"
|
|
|
|
- :selected="selected"
|
|
|
|
- :model="newmodel"
|
|
|
|
- :key="newmodel.id"
|
|
|
|
- >
|
|
|
|
|
|
+ <treeList @on-click="(depth) => $emit('onClick', depth)" @detail-node="(depth) => $emit('detailNode', depth)"
|
|
|
|
+ v-for="newmodel in model.children" :selected="selected" :model="newmodel" :key="newmodel.id">
|
|
<template #icon="slotProps">
|
|
<template #icon="slotProps">
|
|
<slot name="icon" v-bind="slotProps"></slot>
|
|
<slot name="icon" v-bind="slotProps"></slot>
|
|
</template>
|
|
</template>
|
|
@@ -44,141 +33,152 @@
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
- import { computed, ref, } from 'vue';
|
|
|
|
- interface IFileSystem {
|
|
|
|
- id: string;
|
|
|
|
- title: string;
|
|
|
|
- pid: string;
|
|
|
|
- isFolder: boolean;
|
|
|
|
- isAdd: boolean;
|
|
|
|
- children?: IFileSystem[];
|
|
|
|
|
|
+import { computed, ref, } from 'vue';
|
|
|
|
+interface IFileSystem {
|
|
|
|
+ id: string;
|
|
|
|
+ title: string;
|
|
|
|
+ pid: string;
|
|
|
|
+ ppid: string,
|
|
|
|
+ isFolder: boolean;
|
|
|
|
+ isAdd: boolean;
|
|
|
|
+ children?: IFileSystem[];
|
|
|
|
+}
|
|
|
|
+// 吐出去的事件
|
|
|
|
+const emit = defineEmits([
|
|
|
|
+ 'onClick',
|
|
|
|
+ 'detailNode',
|
|
|
|
+]);
|
|
|
|
+// 拿到传入的值
|
|
|
|
+const props = withDefaults(
|
|
|
|
+ defineProps<{
|
|
|
|
+ model: IFileSystem;
|
|
|
|
+ selected: IFileSystem;
|
|
|
|
+ }>(),
|
|
|
|
+ {
|
|
|
|
+ // draggable: false,
|
|
}
|
|
}
|
|
- // 吐出去的事件
|
|
|
|
- const emit = defineEmits([
|
|
|
|
- 'onClick',
|
|
|
|
- 'detailNode',
|
|
|
|
- ]);
|
|
|
|
- // 拿到传入的值
|
|
|
|
- const props = withDefaults(
|
|
|
|
- defineProps<{
|
|
|
|
- model: IFileSystem;
|
|
|
|
- selected: IFileSystem;
|
|
|
|
- }>(),
|
|
|
|
- {
|
|
|
|
- // draggable: false,
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- //是否移入
|
|
|
|
- const isHover = ref(false);
|
|
|
|
- // 是否展开
|
|
|
|
- const expanded = ref(true);
|
|
|
|
- // 是否是文件夹
|
|
|
|
- const isFolder = computed(() => {
|
|
|
|
- return props.model.isFolder;
|
|
|
|
- });
|
|
|
|
- const isSelected = computed(() => props.selected.id === props.model.id);
|
|
|
|
|
|
+);
|
|
|
|
+//是否移入
|
|
|
|
+const isHover = ref(false);
|
|
|
|
+// 是否展开
|
|
|
|
+const expanded = ref(true);
|
|
|
|
+// 是否是文件夹
|
|
|
|
+const isFolder = computed(() => {
|
|
|
|
+ return props.model.isFolder;
|
|
|
|
+});
|
|
|
|
+const isSelected = computed(() => {
|
|
|
|
+ if (props.model.pid == '0' || props.model.pid == '1' || props.model.pid == '2') {
|
|
|
|
+ return props.selected.id === props.model.id && props.selected.pid === props.model.pid;
|
|
|
|
+ } else if (props.model.ppid == '0' || props.model.ppid == '1' || props.model.ppid == '2') {
|
|
|
|
+ return props.selected.id === props.model.id && props.selected.ppid === props.model.ppid;
|
|
|
|
+ } else {
|
|
|
|
+ return props.selected.id === props.model.id ;
|
|
|
|
+ }
|
|
|
|
+})
|
|
// 拖拽样式
|
|
// 拖拽样式
|
|
const treeNodeClass = computed(() => {
|
|
const treeNodeClass = computed(() => {
|
|
- return {
|
|
|
|
- 'vtl-node-main': true,
|
|
|
|
- selected: isSelected.value,
|
|
|
|
- };
|
|
|
|
|
|
+ return {
|
|
|
|
+ 'vtl-node-main': true,
|
|
|
|
+ selected: isSelected.value,
|
|
|
|
+ };
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+// 删除目录
|
|
|
|
+const delNode = () => {
|
|
|
|
+ emit('detailNode', {
|
|
|
|
+ ...props.model,
|
|
|
|
+ eventType: 'detail',
|
|
});
|
|
});
|
|
-
|
|
|
|
- // 删除目录
|
|
|
|
- const delNode = () => {
|
|
|
|
- emit('detailNode', {
|
|
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 展开收起
|
|
|
|
+const toggle = () => {
|
|
|
|
+ if (isFolder.value) {
|
|
|
|
+ console.log(props.model, 'props.model---------')
|
|
|
|
+ expanded.value = !expanded.value;
|
|
|
|
+ emit('onClick', {
|
|
|
|
+ ...props.model,
|
|
|
|
+ }); //lxh
|
|
|
|
+ } else {
|
|
|
|
+ console.log(props.model, 'props.model---------')
|
|
|
|
+ emit('onClick', {
|
|
...props.model,
|
|
...props.model,
|
|
- eventType: 'detail',
|
|
|
|
});
|
|
});
|
|
- };
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- // 展开收起
|
|
|
|
- const toggle = () => {
|
|
|
|
- if (isFolder.value ) {
|
|
|
|
- expanded.value = !expanded.value;
|
|
|
|
- emit('onClick', {
|
|
|
|
- ...props.model,
|
|
|
|
- }); //lxh
|
|
|
|
- } else {
|
|
|
|
- emit('onClick', {
|
|
|
|
- ...props.model,
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- // 拖拽结束
|
|
|
|
- const mouseOver = () => {
|
|
|
|
- isHover.value = true;
|
|
|
|
- };
|
|
|
|
- // 移出
|
|
|
|
- const mouseOut = () => {
|
|
|
|
- isHover.value = false;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+// 拖拽结束
|
|
|
|
+const mouseOver = () => {
|
|
|
|
+ isHover.value = true;
|
|
|
|
+};
|
|
|
|
+// 移出
|
|
|
|
+const mouseOut = () => {
|
|
|
|
+ isHover.value = false;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
</script>
|
|
</script>
|
|
<style lang="less">
|
|
<style lang="less">
|
|
- .vtl-node {
|
|
|
|
- .vtl-node-main {
|
|
|
|
- display: flex;
|
|
|
|
- align-items: center;
|
|
|
|
- padding: 2px 0 2px 2px;
|
|
|
|
- cursor: pointer;
|
|
|
|
-
|
|
|
|
- &:hover {
|
|
|
|
- .vtl-border-text {
|
|
|
|
- width: 80%;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+.vtl-node {
|
|
|
|
+ .vtl-node-main {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ padding: 2px 0 2px 2px;
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
|
|
|
+ &:hover {
|
|
.vtl-border-text {
|
|
.vtl-border-text {
|
|
- display: flex; //lxh
|
|
|
|
- flex: 1;
|
|
|
|
- align-items: center; //lxh
|
|
|
|
- width: 100%;
|
|
|
|
- padding-left: 5px;
|
|
|
|
-
|
|
|
|
- .iconfont {
|
|
|
|
- width: 16px;
|
|
|
|
- height: 16px;
|
|
|
|
- vertical-align: text-bottom;
|
|
|
|
- }
|
|
|
|
|
|
+ width: 80%;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .vtl-border-text {
|
|
|
|
+ display: flex; //lxh
|
|
|
|
+ flex: 1;
|
|
|
|
+ align-items: center; //lxh
|
|
|
|
+ width: 100%;
|
|
|
|
+ padding-left: 5px;
|
|
|
|
|
|
- &.selected {
|
|
|
|
- // background-color: rgba(45, 113, 134, 0.2);
|
|
|
|
- background-color: #1c4869;
|
|
|
|
|
|
+ .iconfont {
|
|
|
|
+ width: 16px;
|
|
|
|
+ height: 16px;
|
|
|
|
+ vertical-align: text-bottom;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &.selected {
|
|
|
|
+ // background-color: rgba(45, 113, 134, 0.2);
|
|
|
|
+ background-color: #1c4869;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
+ .vtl-node-content {
|
|
|
|
+ color: #fff;
|
|
|
|
+ padding-left: 5px;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ width: 80%;
|
|
|
|
+ display: inline-block;
|
|
|
|
+ vertical-align: bottom;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &:hover {
|
|
.vtl-node-content {
|
|
.vtl-node-content {
|
|
color: #fff;
|
|
color: #fff;
|
|
- padding-left: 5px;
|
|
|
|
- font-size: 14px;
|
|
|
|
- width: 80%;
|
|
|
|
- display: inline-block;
|
|
|
|
- vertical-align: bottom;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- &:hover {
|
|
|
|
- .vtl-node-content {
|
|
|
|
- color: #fff;
|
|
|
|
- overflow: hidden;
|
|
|
|
- }
|
|
|
|
|
|
+ overflow: hidden;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- .vtl-operation {
|
|
|
|
- padding-right: 10px;
|
|
|
|
- }
|
|
|
|
|
|
+ .vtl-operation {
|
|
|
|
+ padding-right: 10px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- .vtl-tree-margin {
|
|
|
|
- padding-left: 1em;
|
|
|
|
- }
|
|
|
|
|
|
+.vtl-tree-margin {
|
|
|
|
+ padding-left: 1em;
|
|
|
|
+}
|
|
</style>
|
|
</style>
|