基于 Ant Design Vue实现tree的增删改
背景:
在维护的项目是基于Ant Design Vue 框架实现的,需求是新建时,前端需要将树形结构维护完成后,一次性调用接口进行下发,在网上找了半天资料,要不源码不全,要不就是增删改后实时和后台交互,不符合要求,所以在这里将实现过程写出来,仅供学习交流。
使用前须知:
-
因为Vue3的项目,所以首先需要初始化Vue3的项目
-
因为基于Ant Design Vue框架实现,所以需要安装Ant Design Vue组件库
实现步骤:
- 使用命令
npm init vue@latest
初始化Vue3项目(如果是已有项目中使用,就不需要这个步骤了)
选择自己所需安装内容:
- 进入项目文件下,安装依赖后启动
cd <your-project-name>
npm install
npm run dev
-
安装Ant Design Vue:
npm i --save ant-design-vue
-
在main.js引入:
import { createApp } from 'vue'
import App from './App.vue'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
createApp(App).use(Antd).mount('#app')
-
因为要使用 Ant Design Vue的icon图标,所以安装该组件:
npm install --save @ant-design/icons-vue
-
直接在App.vue中写这个demo
<template>
<header>
ant-design-vue tree 增删改
</header>
<main>
<a-button type="primary" @click="addComp" v-if="!treeData.length">添加根节点</a-button>
<a-tree v-if="treeData && treeData.length > 0" :autoExpandParent="true" :tree-data="treeData" :defaultExpandAll="true" showLine blockNode>
<template v-slot:title="nodeData">
<span> {{nodeData.name}} </span>
<a-button-group style="float:right">
<!-- <a-button size="small" @click="slotAddSame(nodeData)" icon="plus-circle" title="添加同级"></a-button>-->
<a-button size="small" @click="addComp(nodeData)" title="添加下级">
<plus-square-outlined />
</a-button>
<a-button size="small" @click="slotModify(nodeData)" title="修改">
<form-outlined />
</a-button>
<a-popconfirm title="确定删除该节点吗?" ok-text="确定" cancel-text="取消" @confirm="confirmDel">
<a-button size="small" @click="slotDelete(nodeData)" title="删除">
<delete-outlined />
</a-button>
</a-popconfirm>
</a-button-group>
</template>
</a-tree>
<a-modal v-model:visible="visible" title="新建节点" @ok="handleOk">
名称:<a-input v-model:value="compName" placeholder="请输入节点名称" />
</a-modal>
<a-button class="get-btn" type="primary" @click="getTreeData" v-if="treeData.length">获取树的值</a-button>
</main>
</template>
<script setup>
import {
PlusSquareOutlined,
FormOutlined,
DeleteOutlined
} from '@ant-design/icons-vue';
import { notification } from 'ant-design-vue';
import { ref, toRaw } from 'vue';
const treeData = ref([])
const parentNode = ref({})
const visible = ref(false);
const compName = ref('')
const isUpdate = ref(false)
const showModal = () => {
visible.value = true;
};
const handleOk = () => {
if (isUpdate.value) {
Object.assign(parentNode.value.dataRef, { name: compName.value})
} else {
if (!parentNode.value.name) {
treeData.value.push({ name: compName.value, children: [], key: 0 })
} else {
parentNode.value.children.push({ name: compName.value, children: [], key: Math.random() })
}
}
visible.value = false;
};
// 增加下级节点
function addComp(nodeData){
isUpdate.value = false
compName.value = ''
parentNode.value = nodeData
showModal()
}
// 修改当前节点
function slotModify(nodeData) {
isUpdate.value = true
parentNode.value = nodeData
compName.value = nodeData.dataRef.name
showModal()
}
// 删除当前节点
function slotDelete(nodeData) {
parentNode.value = nodeData
}
// 确认删除当前节点
function confirmDel() {
Object.assign(parentNode.value.dataRef, null)
searchOption(parentNode.value.dataRef, treeData.value)
}
// 递归查找操作的节点,在父节点的children中删除
function searchOption (option, arr, obj = {}) {
//首先循环arr最外层数据
for (let s = 0; s < arr.length; s++) {
//如果匹配到了arr最外层中的我需要删除的数据
if (arr[s].key === option.key) {
//删除即删除即可
arr.splice(s, 1)
break
} else if (arr[s].children && arr[s].children.length > 0) {
// 递归条件
searchOption(option, arr[s].children, obj)
} else {
continue
}
}
}
// 弹框
const openNotification = (msg) => {
notification.open({
message: 'tree value',
description: msg,
onClick: () => {
console.log('Notification Clicked!');
},
duration: 3,
});
};
// 获取当前树的值
function getTreeData() {
let details = toRaw(treeData.value)
console.log(details)
openNotification(JSON.stringify(details))
}
</script>
<style scoped>
header {
display: flex;
justify-content: center;
align-items: flex-start;
font-weight: 600;
}
main{
margin: 100px 400px;
}
.get-btn {
margin-top: 50px;
}
</style>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了