vue自定义树形选择

tech2022-08-16  136

1.树引用组件

<template> <div class="h100 treeLeft radius5 hidden"> <div class="treeLeftDom relative paddingB20 h100 w100"> <div class="absolute w100 treeTop flex justify-between items-center"> <el-avatar :size="30" icon="icon iconfont icon-xiangqing"></el-avatar> <span class="enterpriseTitle">{{enterprise.name}}</span> <div class="paddingR5 operationBtn flex items-center"> <i class="el-icon-arrow-down cursor"></i> </div> </div> <div class="paddingT10 w100 h100 overflow"> <TreeA v-for="node in treeData" :selectId="selectId" @change="nodeChange" :level="-1" :key="node.id" :node="node"/> </div> </div> </div> </template> <script> import TreeA from "./TreeA"; export default { name: "OrgStructureLeft", components: {TreeA}, data() { return { isOpenTree: true, treeData: [], selectId: '3c58d359a90b46ee83f0113b7f4cd811', enterprise: {id: '', name: '', parentId: ''}, defaultProps: { children: 'childDepartment', label: 'name' } } }, computed: { ...mapState(['currentEnterprise']) }, methods: { departmentsTree() { this.httpClient.get(this.baseInfo.departmentsTree, {}, ({childDepartment, id, name, parentId}) => { this.enterprise = {childDepartment, id, name, parentId}; this.treeData = childDepartment || []; this.sessionSave.save('departmentTree',this.enterprise); if(childDepartment&&childDepartment.length){ this.$emit('nodeChange',{...childDepartment[0]}) } }) }, /** * 节点点击事件 * @param id 部门ID * @param name 部门名称 */ nodeChange({id,name}) { this.selectId = id; this.$emit('nodeChange',{id,name}) } }, mounted() { this.departmentsTree() }, watch: { currentEnterprise: 'departmentsTree' } } </script> <style scoped> .treeLeftDom { padding-top: 30px; } .treeLeft { padding: 10px 4px; float: left; width: 280px; background-color: #F8F8F8; } .title { padding: 0 4px; width: 28rem; font-size: 14px; } .treeTop { top: 0; left: 0; padding: 0 50px; height: 30px; background-color: #F8F8F8; } .el-avatar { position: absolute; top: 0; left: 10px; } .enterpriseTitle { line-height: 30px; } .operationBtn { position: absolute; height: 30px; top: 0; right: 0; } </style>

2.编写组件

<template> <div> <div :class="'paddingV10 cursor '+(selectId===node.id?'isSelect':'noSelect')" :style="{paddingLeft:(50+levelNum*20)+'px'}"> <div class="relative paddingL30 optionBtn"> <i class="absolute circle marginR20"></i> <div class="over-text-row w100" @click="$emit('change',node)">{{node.name}}</div> <div class="paddingL10 optionBtnDom absolute flex justify-end items-center"> <i v-show="isHave" :class="'el-icon-arrow-'+(nodeShow?'down':'up')" @click="nodeShow=!nodeShow"></i> <i class="el-icon-plus"></i> <i class="icon iconfont icon-icon_edit"></i> <i class="icon iconfont icon-shanchu"></i> </div> </div> </div> <TreeA v-show="nodeShow" v-for="item in node.childDepartment" :selectId="selectId" :level="levelNum" :key="item.id" :node="item" @change="nodeId=>($emit('change',nodeId))"/> </div> </template> <script> export default { name: "TreeA", props: ['node', 'level', 'selectId'], computed:{ isHave:function () { if(!this.node.childDepartment){ return false } return this.node.childDepartment.length>0 } }, data() { return { levelNum: 0, nodeShow: true } }, mounted() { this.levelNum = this.level + 1 } } </script> <style scoped lang="scss"> .isSelect { .circle { border: 1px solid #007AFF; } .over-text-row, .el-icon-arrow-down, .circle { color: #007AFF; } } .noSelect { .circle { border: 1px solid #101010; } .over-text-row, .circle { color: #101010; } } .circle { content: ''; top: 8px; left: 5px; display: block; width: 8px; height: 8px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .optionBtn { padding-right: 25px; } .optionBtnDom { top: 0; right: 0; padding-right: 5px; } .icon-icon_edit, .icon-shanchu { font-size: 14px; } .icon-icon_edit, .icon-shanchu, .el-icon-plus { display: none; } .optionBtn:hover { .icon-icon_edit, .icon-shanchu, .el-icon-plus { display: inline-block; } .optionBtnDom { width: 100px; } padding-right: 100px; } .optionBtnDom>i+i{ margin-left: 5px; } </style>

 

3.显示效果

最新回复(0)