| | |
| | | <template> |
| | | <div class="table-overlay"> |
| | | <div class="topBar"> |
| | | <div |
| | | v-for="(item, index) in tabData" |
| | | :key="index" |
| | | :class="{ 'active-tab': activeTab === index }" |
| | | @click="activeTab = index" |
| | | > |
| | | {{ item.name }} |
| | | </div> |
| | | </div> |
| | | <div class="searchBox"> |
| | | <el-input |
| | | class="ztzf-input inputName" |
| | | v-model="formData.dkbh" |
| | | placeholder="图斑名称" |
| | | placeholder="输入名称模糊搜索" |
| | | ></el-input> |
| | | <div class="searchAndReset"> |
| | | <div class="reset" @click="reset">重置</div> |
| | | <div class="search" @click="search">搜索</div> |
| | | <el-button type="primary" icon="el-icon-search" @click="search">搜索</el-button> |
| | | <el-button class="ztzf-button" icon="el-icon-refresh" @click="reset">清空</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="btnGroups"> |
| | | <el-button type="primary">新增围栏</el-button> |
| | | <el-button type="success">新增文件夹</el-button> |
| | | <el-button type="info" @click="selectAll">全选</el-button> |
| | | <el-button class="ztzf-button" @click="addFence">新增围栏</el-button> |
| | | <el-button class="ztzf-button" @click="addFolder">新增文件夹</el-button> |
| | | <el-button class="ztzf-button" @click="selectAll">全选</el-button> |
| | | </div> |
| | | <div class="tableListBox"> |
| | | <el-tree |
| | | v-model="checkedKeys" |
| | | :data="treeData" |
| | | show-checkbox |
| | | node-key="id" |
| | | default-expand-all |
| | | :props="{ |
| | | label: 'name', |
| | | children: 'children', |
| | | }" |
| | | /> |
| | | <el-tree |
| | | class="ztzf-el-tree" |
| | | ref="treeRef" |
| | | v-model="checkedKeys" |
| | | :data="treeData" |
| | | show-checkbox |
| | | node-key="id" |
| | | default-expand-all |
| | | @check="handleCheck" |
| | | :props="{ |
| | | label: 'name', |
| | | children: 'children', |
| | | }" |
| | | > |
| | | <!-- 自定义节点内容 --> |
| | | <template #default="{ node }"> |
| | | <div class="tree-node"> |
| | | <!-- 节点名称 --> |
| | | <span>{{ node.label }}</span> |
| | | <!-- 操作按钮组 --> |
| | | <div class="tree-node-actions"> |
| | | <el-button icon="el-icon-location" type="text" @click="handleLocation(node)"></el-button> |
| | | <el-button icon="el-icon-edit" type="text" @click="handleEdit(node)"></el-button> |
| | | <el-button icon="el-icon-delete" type="text" @click="handleDelete(node)"></el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </el-tree> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import { treeDataApi } from '@/api/layer/index'; |
| | | import { onMounted } from 'vue'; |
| | | const emit = defineEmits(['update:coverData']); |
| | | const coverData = ref(); |
| | | const props = defineProps(['activeName']); |
| | | const formData = { |
| | | isPush: undefined, |
| | | page: 1, |
| | |
| | | dkbh: '', |
| | | patchesName: '', |
| | | }; |
| | | const tabData = ref([ |
| | | { |
| | | name: '电子围栏', |
| | | type: '0', |
| | | }, |
| | | { |
| | | name: '自定义禁飞区', |
| | | type: '1', |
| | | }, |
| | | { |
| | | name: '国土空间规划', |
| | | type: '2', |
| | | }, |
| | | ]); |
| | | |
| | | const activeTab = ref(0); |
| | | const handelClick = val => { |
| | | activeTab.value = val.type; |
| | | }; |
| | | const reset = () => {}; |
| | | const search = () => {}; |
| | | const treeData = ref([ |
| | | { |
| | | id: 'group1', |
| | | name: '道路裂缝识别', |
| | | children: [ |
| | | { id: 'road1', name: '桃花路' }, |
| | | { id: 'road2', name: '洪城路' }, |
| | | { id: 'road3', name: '中山路' }, |
| | | ], |
| | | }, |
| | | { |
| | | id: 'group2', |
| | | name: '电动车识别', |
| | | children: [ |
| | | { id: 'electric1', name: '桃新大道' }, |
| | | { id: 'electric2', name: '昌南大道' }, |
| | | ], |
| | | }, |
| | | ]); |
| | | |
| | | const treeData = ref([]); |
| | | const treeAllData = ref([]); |
| | | // 获取数据 |
| | | const gettreeDataApi = async () => { |
| | | try { |
| | | const res = await treeDataApi(); |
| | | treeAllData.value = res.data.data; |
| | | console.log('接口获取数据', treeAllData.value); |
| | | setupWatch(); |
| | | } catch (error) { |
| | | console.error('获取数据失败:', error); |
| | | } |
| | | }; |
| | | const setupWatch = () => { |
| | | watch( |
| | | () => props.activeName, |
| | | newVal => { |
| | | const matchedCategory = treeAllData.value.find(item => item.name === newVal); |
| | | treeData.value = matchedCategory.children; |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | }; |
| | | const checkedKeys = ref([]); // 存储勾选的节点key |
| | | const treeRef = ref(null); // 获取tree实例 |
| | | |
| | | const checkedNodes = ref([]); // 存储勾选的节点数据 |
| | | |
| | | const handleCheck = (checkedNodesData, checkedKeysData) => { |
| | | checkedNodes.value = checkedNodesData.checkedNodes; |
| | | |
| | | coverData.value = checkedKeysData.checkedNodes; |
| | | |
| | | emit('update:coverData', coverData.value); |
| | | // console.log('选中的节点数据:', checkedKeysData); |
| | | }; |
| | | // 全选方法 |
| | | const selectAll = () => { |
| | | const allKeys = []; |
| | | // 递归收集所有节点的id |
| | | const collectKeys = data => { |
| | | data.forEach(item => { |
| | | allKeys.push(item.id); |
| | | if (item.children) { |
| | | collectKeys(item.children); |
| | | } |
| | | }); |
| | | }; |
| | | collectKeys(treeData.value); |
| | | checkedKeys.value = allKeys; |
| | | console.log('全选', checkedKeys.value); |
| | | if (treeRef.value) { |
| | | // 获取所有节点的key |
| | | const allKeys = treeData.value.flatMap(item => [ |
| | | item.id, |
| | | ...item.children.map(child => child.id), |
| | | ]); |
| | | |
| | | if (checkedKeys.value.length === allKeys.length) { |
| | | // 如果已经全选,则取消全选 |
| | | treeRef.value.setCheckedKeys([]); |
| | | checkedNodes.value = []; |
| | | } else { |
| | | // 否则全选 |
| | | treeRef.value.setCheckedKeys(allKeys); |
| | | // 获取所有节点数据 |
| | | checkedNodes.value = treeData.value.flatMap(item => [ ...item.children]); |
| | | console.log('所有数据', checkedNodes.value); |
| | | } |
| | | } |
| | | }; |
| | | // 定位按钮事件 |
| | | const handleLocation = (node) => { |
| | | console.log('定位操作,节点:', node); |
| | | |
| | | |
| | | }; |
| | | |
| | | // 编辑按钮事件 |
| | | const handleEdit = (node) => { |
| | | console.log('编辑操作,节点:', node.data); |
| | | emit('update:coverData', [node.data]); |
| | | |
| | | }; |
| | | |
| | | // 删除按钮事件 |
| | | const handleDelete = (node) => { |
| | | console.log('删除操作,节点:', node.data); |
| | | |
| | | }; |
| | | // 新增围栏 |
| | | const addFence =()=>{ |
| | | |
| | | } |
| | | // 新增文件夹 |
| | | const addFolder =()=>{ |
| | | |
| | | } |
| | | onMounted(() => { |
| | | gettreeDataApi(); |
| | | }); |
| | | const changeClick = val => {}; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | height: 99%; |
| | | height: 95%; |
| | | z-index: 99; |
| | | width: 377px; |
| | | height: 100%; |
| | | width: 392px; |
| | | |
| | | overflow: hidden; |
| | | background: rgba(0, 0, 0, 0.8); |
| | | border-radius: 8px 8px 8px 8px; |
| | | padding: 6px 10px 0 10px 10px 0 10px; |
| | | padding: 16px 12px; |
| | | } |
| | | |
| | | .topBar { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | color: #fff; |
| | | font-size: 16px; |
| | | |
| | | div { |
| | | padding: 8px 12px; |
| | | cursor: pointer; |
| | | position: relative; |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | color: #409eff; // 悬停颜色 |
| | | } |
| | | |
| | | &.active-tab { |
| | | color: #409eff; // 激活颜色 |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | bottom: 0; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | width: 60%; |
| | | |
| | | width: 60%; |
| | | height: 2px; |
| | | background-color: #409eff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .searchBox { |
| | | display: flex; |
| | | margin-top: 10px; |
| | | .inputName { |
| | | width: 184px; |
| | | height: 32px; |
| | | } |
| | | .searchAndReset { |
| | | width: 182px; |
| | | display: flex; |
| | |
| | | } |
| | | |
| | | .reset { |
| | | margin-right: 7px; |
| | | margin-left: 12px; |
| | | background: #0d2b38; |
| | | border-radius: 4px 4px 4px 4px; |
| | | border: 1px solid #84cbd3; |
| | |
| | | } |
| | | } |
| | | .btnGroups { |
| | | margin-top: 10px; |
| | | margin: 12px 0 14px 0; |
| | | display: flex; |
| | | } |
| | | .tableListBox { |
| | | .tree-node { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | width: 100%; |
| | | } |
| | | |
| | | .tree-node-actions { |
| | | display: flex; |
| | | gap: 8px; // 按钮之间的间距 |
| | | button { |
| | | padding: 0; // 清除默认内边距 |
| | | color: #fff; // 按钮图标颜色 |
| | | &:hover { |
| | | color: #409eff; // hover 时的颜色 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | </style> |