java+vue3+el-tree實(shí)現(xiàn)樹形結(jié)構(gòu)操作代碼
基于springboot + vue3 elementPlus實(shí)現(xiàn)樹形結(jié)構(gòu)數(shù)據(jù)的添加、刪除和頁(yè)面展示
效果如下
代碼如下,業(yè)務(wù)部分可以自行修改
java后臺(tái)代碼
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.daztk.mes.common.annotation.LogOperation; import com.daztk.mes.common.utils.Result; import com.daztk.mes.module.cad.dto.CadPartDto; import com.daztk.mes.module.cad.entity.CadPart; import com.daztk.mes.module.cad.entity.CadRelation; import com.daztk.mes.module.cad.service.ICadPartService; import com.daztk.mes.module.cad.service.ICadRelationService; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.*; import java.util.stream.Collectors; /** * <p> * 零部件 * </p> * * @since 2024-05-30 */ @RestController @RequestMapping("cad/part") public class CadPartController { @Autowired ICadPartService service; @Autowired ICadRelationService relationService; /** * 獲取所有零部件 * @param dto * @return */ @GetMapping("listAll") public Result listAll(CadPartDto dto){ List<CadPart> list = new ArrayList<>(); try { list = service.getList(dto); if(CollectionUtils.isNotEmpty(list)){ list = getTree(list); } } catch (Exception e) { e.printStackTrace(); return new Result().err(); } return new Result().ok().setData(list); } @PostMapping("add") @LogOperation(tags = "CAD管理-零部件",serviceClass = ICadPartService.class,entityClass = CadPart.class) public Result add(@RequestBody CadPart cadPart){ try { service.saveData(cadPart); } catch (Exception e) { e.printStackTrace(); return new Result().err(); } return new Result().ok().setData(cadPart); } @DeleteMapping("delete") @LogOperation(tags = "CAD管理-零部件",serviceClass = ICadPartService.class,entityClass = CadPart.class) public Result delete(@RequestBody Long[] ids){ try { List<Long> idList = Arrays.asList(ids); List<Long> list = recurveIdList(idList); service.removeByIds(list); } catch (Exception e) { e.printStackTrace(); return new Result().err(); } return new Result().ok(); } /** * 遞歸獲取id樹 * * @param ids * @return */ public List<Long> recurveIdList(List<Long> ids){ List<Long> list = new ArrayList<>(); for(Long id: ids){ list.add(id); //關(guān)系表查子集 List<CadRelation> cadRelations = relationService.list(new QueryWrapper<CadRelation>().eq("parent_id", id)); if(CollectionUtils.isNotEmpty(cadRelations)){ List<Long> partIds = cadRelations.stream().map(CadRelation::getPartId).collect(Collectors.toList()); List<Long> list1 = recurveIdList(partIds); list.addAll(list1); } } return list; } public List<CadPart> getTree(List<CadPart> treeList){ List<CadPart> collect = treeList.stream() .filter(item -> item.getParentId() == 0)//構(gòu)造最外層節(jié)點(diǎn),即id=0的節(jié)點(diǎn) .map(item -> { item.setChildren(getChildren(item, treeList));//id=0的節(jié)點(diǎn)就為他設(shè)置子節(jié)點(diǎn) return item; }). collect(Collectors.toList()); return collect; } private static List<CadPart> getChildren(CadPart treeEntity, List<CadPart> treeEntityList) { List<CadPart> collect = treeEntityList.stream() .filter(item -> item.getParentId().equals(treeEntity.getId()))//判斷當(dāng)前節(jié)點(diǎn)的父id是不是要設(shè)置節(jié)點(diǎn)的id .map(item -> { item.setChildren(getChildren(item, treeEntityList));//如果是 為其設(shè)置子節(jié)點(diǎn) 通過遞歸 為每個(gè)除了最外層節(jié)點(diǎn)的節(jié)點(diǎn)設(shè)置子節(jié)點(diǎn) return item; }) .collect(Collectors.toList()); return collect; }
前端代碼
<template> <div class="custom-tree-container"> <!-- <p>Using render-content</p> <el-tree style="max-width: 600px" :data="dataSource" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false" :render-content="renderContent" /> --> <el-button type="primary" class="add-btn" icon="el-icon-circle-plus-outline" @click="addEdit">新增零部件</el-button> <div style="padding-top: 20px;"> <el-tree style="max-width: 600px; " :data="dataSource" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false" ref="treeRef" :props="mapProps"> <template #default="{ node, data }"> <span class="custom-tree-node"> <span>{{ node.label }}</span> <span> <a @click="append(data)"> 增加子節(jié)點(diǎn) </a> <a style="margin-left: 8px" @click="removeNode(node, data)"> 刪除 </a> </span> </span> </template> </el-tree> </div> <el-dialog :title="title" v-model="drawer" width="600px"> <el-form :model="partForm" :rules="rules" ref="ruleFormsss" label-width="120px" class="demo-partForm"> <el-form-item label="數(shù)模號(hào):" prop="partNo"> <el-input v-model="partForm.partNo" clearable></el-input> </el-form-item> <el-form-item label="版本號(hào):" prop="partRev"> <el-input v-model="partForm.partRev" clearable></el-input> </el-form-item> <el-form-item label="名稱:" prop="name"> <el-input v-model="partForm.name" clearable></el-input> </el-form-item> <el-form-item label="中文名稱:" prop="cName"> <el-input v-model="partForm.cName" clearable></el-input> </el-form-item> <el-form-item label="材料:" prop="material"> <el-input v-model="partForm.material" clearable></el-input> </el-form-item> <el-form-item label="規(guī)格:" prop="gauge"> <el-input v-model="partForm.gauge" clearable></el-input> </el-form-item> <el-form-item label="重量:" prop="massqty"> <el-input v-model="partForm.massqty" clearable></el-input> </el-form-item> <el-form-item label="數(shù)據(jù)類型:" prop="partType"> <el-input v-model="partForm.partType" clearable></el-input> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="cancelEdit">取 消</el-button> <el-button type="primary" @click="saveEdit">確 定</el-button> </span> </template> </el-dialog> </div> </template> <script> import { reactive, ref, toRefs, unref, onMounted } from 'vue' import { add, remove, listAll } from '@api/cad/part' import { ElMessage } from 'element-plus' export default { name: 'part', setup() { const state = reactive({ drawer: false, title: '', query: { partName: '' }, dataSource: [ // { // id: 1, // label: 'Level one 1', // children: [] // // children: [ // // { // // id: 4, // // label: 'Level two 1-1', // // children: [ // // { // // id: 9, // // label: 'Level three 1-1-1' // // } // // ] // // } // // ] // } ], mapProps: { id: 'id', label: 'name', children: 'children' } }) const treeRef = ref(null) const append = (data) => { state.drawer = true state.title = '添加子節(jié)點(diǎn)' partForm.parentId = data.id partForm.partNo = '' partForm.partRev = '' partForm.name = '' partForm.cName = '' partForm.material = '' partForm.gauge = '' partForm.massqty = '' partForm.partType = '' // debugger // 獲取當(dāng)前節(jié)點(diǎn) // const currentNode = treeRef.value.getNode(data.id) // // 獲取當(dāng)前節(jié)點(diǎn)在樹中的索引 // // const currentIndex = getNod(data.id) // // // 如果索引大于 0,獲取前一個(gè)節(jié)點(diǎn) // // if (currentIndex > 0) { // // const prevNode = getNodeAt(currentIndex - 1); // // const prevId = prevNode.id; // // // 處理前一個(gè)節(jié)點(diǎn)的 id // // } // let treeNodeId = data.$treeNodeId //節(jié)點(diǎn)id // console.info(data) // // alert('當(dāng)前id'+data.id) // // alert(data.$treeNodeId) // let id = null // if (!data.children || data.children.length == 0) { // //沒有子節(jié)點(diǎn) // id = data.id * 100 + 1 // } else { // id = data.id * 100 + 1 + data.children.length // } // const newChild = { id: id, label: data.label + '-' + id, children: [] } // const child = [{ id: id, label: data.label + '-' + id, children: [] }] // data.children = child // data.push() // state.dataSource = [data]; } const removeNode = (node, data) => { const ids = [] ids.push(data.id) remove(ids).then(res => { if (res.code == 200) { ElMessage({ type: 'success', message: '刪除成功' }) getPartTableData(state.query) } else { ElMessage({ type: 'error', message: res.msg }) } }) // dataSource.value = [...dataSource.value]; } const partForm = reactive({ partNo: '', partRev: '', name: '', cName: '', material: '', gauge: '', massqty: '', partType: '', parentId: '' }) const ruleFormsss = ref(null) const addEdit = () => { state.drawer = true state.title = '添加零部件' partForm.parentId = '' partForm.partNo = '' partForm.partRev = '' partForm.name = '' partForm.cName = '' partForm.material = '' partForm.gauge = '' partForm.massqty = '' partForm.partType = '' } // 取消 const cancelEdit = () => { state.drawer = false setTimeout(() => { const form = unref(partFormsss) form.resetFields() }, 100) } // 新建/編輯零部件 const saveEdit = async () => { const form = unref(ruleFormsss) if (!form) return try { await form.validate() if (state.title == '添加零部件' || state.title == '添加子節(jié)點(diǎn)') { addSavePart() } if (state.title == '編輯零部件') { updateSavePart() } state.drawer = false } catch (error) { console.error(error) ElMessage.error('抱歉,您有必填項(xiàng)未填!') } } const addSavePart = () => { // let quantity = partForm.quantity + partForm.iQuantity const data = { partNo: partForm.partNo, partRev: partForm.partRev, name: partForm.name, cName: partForm.cName, material: partForm.material, gauge: partForm.gauge, massqty: partForm.massqty, partType: partForm.partType, parentId: partForm.parentId } add(data).then(res => { state.drawer = false // const treeData = { // id: res.data.id, // label: res.data.name, // children: [] // } // state.dataSource = res.data getPartTableData(state.query) ElMessage.success('恭喜您,添加成功!') }) } const updateSavePart = () => { const data = { id: state.handleId, name: partForm.name, manager: partForm.manager, startDate: partForm.startDate, endDate: partForm.endDate } update(data).then(res => { state.drawer = false getPartTableData(state.query) ElMessage.success('恭喜您,保存成功!') }) } const rules = { name: [{ required: true, message: '此處為必填項(xiàng)', trigger: 'blur' }] } function getPartTableData() { listAll(state.query).then(res => { state.dataSource = res.data }) } onMounted(() => { getPartTableData() }) return { ...toRefs(state), append, removeNode, addEdit, cancelEdit, treeRef, partForm, ruleFormsss, saveEdit, rules } } } </script> <style lang="scss" > .el-tree-node { margin-top: 8px; } .custom-tree-node { flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 18px; padding-right: 8px; } </style>
到此這篇關(guān)于java+vue3+el-tree實(shí)現(xiàn)樹形結(jié)構(gòu)操作的文章就介紹到這了,更多相關(guān)java樹形結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Web MVC和Hibernate的集成配置詳解
這篇文章主要介紹了Spring Web MVC和Hibernate的集成配置詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下2017-12-12Java技巧函數(shù)方法實(shí)現(xiàn)二維數(shù)組遍歷
這篇文章主要介紹了Java技巧函數(shù)方法實(shí)現(xiàn)二維數(shù)組遍歷,二維數(shù)組遍歷,每個(gè)元素判斷下是否為偶數(shù),相關(guān)內(nèi)容需要的小伙伴可以參考一下2022-08-08SpringMVC獲取HTTP中元素的實(shí)現(xiàn)示例
本文主要介紹了SpringMVC獲取HTTP中的元素,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02使用graalvm為帶有反射功能的java代碼生成native?image的示例詳解
graalvm讓native鏡像支持反射的關(guān)鍵是利用json提前告訴它哪些類的哪些方法會(huì)被反射調(diào)用,然后它就能力在運(yùn)行時(shí)支持反射了,這篇文章主要介紹了如何使用graalvm為帶有反射功能的java代碼生成native?image,需要的朋友可以參考下2024-02-02