以前寫的,原本是如下拉列表展現,可是客戶應要求以樹的形式展現,百度了很久,沒有找到合適的適合的樹組件,最後只能本身上手了,展現效果以下:
vue
<style> .treeList { line-height: 40px; font-size: 14px; overflow: hidden; } .parentTree { position: relative; } .closeli { position: absolute; right: 10px; top: 0; } .treeList .mui-icon-checkmarkempty { color: #3498fe; font-size: 30px; } </style> <template> <li class="treeList"> <div :style="style"> <div class="parentTree"> <span @click="nodeClick(node)">{{node.entityTitle}}</span> <span class="mui-icon" :class="node.isChecked?'mui-icon-checkmarkempty':''"></span> <div v-if="node.children && node.children.length > 0" class="closeli"> <span @click="changeStatus(node)" class="mui-icon" :class="node.close?'mui-icon-arrowdown':'mui-icon-arrowup'"></span> <!-- <i @click="changeStatus(node)" v-else>摺疊</i> --> </div> </div> </div> <tree-node @push="push" @remove="remove" v-show="!node.close" :level="level+2" :ref="'children'+index" :key="index" v-for="(item,index) in node.children" :node="item"></tree-node> </li> </template> <script> import linq from 'linq' export default { data: function () { return { style: { paddingLeft: '', borderBottom: '1px solid #dedede' }, vals: [] } }, props: ['node', 'ids', 'level'], methods: { // 展開狀態變動 changeStatus: function (node) { if (node) { if (node.close) { node.close = false } else { node.close = true } } }, // 遞歸設置子節點的狀態 setChildrensRole: function (node, val) { var that = this if (node.children !== null && node.children.length > 0) { node.children.forEach(function (item, index) { item.isChecked = val if (item.children !== null) { that.setChildrensRole(item, val) } }) } }, nodeClick: function (node) { node.isChecked = !node.isChecked this.setChildrensRole(node, node.isChecked) }, removeItem: function (val) { let index = linq.from(this.vals).indexOf(val) this.vals = this.vals.splice(index, 1, 0) console.log(this.vals) }, push: function (val) { this.$emit('push', val) }, remove: function (val) { console.log(val) this.$emit('remove', val) } }, watch: { node: function () { this.$set(this.node, 'close', true) this.$set(this.node, 'isChecked', false) }, 'node.isChecked': function (val) { if (this.node.children && this.node.children.length === 0) { if (val) { this.$emit('push', { id: this.node.entityCode, text: this.node.entityTitle }) } else { this.$emit('remove', { id: this.node.entityCode, text: this.node.entityTitle }) } } } }, created: function () { this.$set(this.node, 'close', true) this.$set(this.node, 'isChecked', false) if (!this.level) { this.level = 0 } this.style.paddingLeft = (this.level * 10) + 'px' }, components: { TreeNode: resolve => require(['./treeNode.vue'], resolve) } } </script>
<template> <div style="overflow-y:auto"> <ul style="padding-left:5px" class="tree"> <tree-node :level="0" @push="push" @remove="remove" :ids="ids" v-for="(item,index) in datas" :key="index" :node="item"></tree-node> </ul> </div> </template> <script> import linq from 'linq' export default { data () { return { ids: this.value, datas: [], labels: [] } }, props: ['nodes', 'value', 'isNeedChangData'], components: { TreeNode: resolve => require(['./treeNode.vue'], resolve) }, watch: { nodes: function (val) { this.datas = this.GetData(0, val) } }, created () { this.datas = this.GetData(0, this.nodes) }, methods: { GetData: function (id, arry = this.nodes) { let [vm, list] = [this, []] var childArry = this.GetParentArry(id, arry) if (childArry.length > 0) { for (var i in childArry) { let test = { entityCode: childArry[i].entityCode, entityTitle: childArry[i].entityTitle, children: vm.GetData(childArry[i].entityId, arry) } list.push(test) } } return list }, GetParentArry: function (id, arry) { var newArry = [] for (var i in arry) { if (arry[i].parentId === id) { newArry.push(arry[i]) } } return newArry }, push: function (val) { if (linq.from(this.ids).indexOf(val.id) < 0) { this.ids.push(val.id) this.labels.push(val.text) this.$emit('input', this.ids) this.$emit('update:labels', this.labels) } }, remove: function (val) { let index = linq.from(this.ids).indexOf(val.id) if (index > -1) { this.ids.splice(index, 1) this.labels.splice(index, 1) } this.$emit('input', this.ids) this.$emit('update:labels', this.labels) } } } </script> <style v-once scoped> ul.tree ul { margin-left: 0; } ul.tree li { margin: 0; padding: 0; line-height: 40px; color: #222; border-top-right-radius: 0px; border-top-left-radius: 0px; } ul.tree .licheckbox { float: left; width: 20px; } .positions ul li:last-child { border-bottom: none !important; } .positions { border-right: 1px solid; } </style>
<tree v-model="ids" :labels.sync="orgSelectLabels" :nodes="ownerGroups"></tree>
:labels.sync="orgSelectLabels"用於回顯到前面選中的展現node