123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- <template>
- <div class="nav-tree">
- <el-input class="filter" v-model="filter" :placeholder="placeholder" size="mini" clearable></el-input>
- <el-tree
- ref="tree"
- :show-checkbox="showCheckbox"
- :getCheckedNodes="true"
- :data="treeItems"
- :props="navProps"
- node-key="id"
- @node-click="handleNavClick"
- @check-change="handleCheckChange"
- :highlight-current="true"
- :expand-on-click-node="false"
- >
- <template v-slot="{ node, data }">
- <slot>
- <span v-if="node.label.length <= 8 - node.level" class="dept-tree-node">
- <i :class="iconCls(data.icon || 'folder')" style="margin-right: 5px;" v-if="showIcon"></i>
- <span>{{ node.label }}</span>
- <el-badge :value="data.desc" class="item" type="info"></el-badge>
- </span>
- <el-tooltip v-else effect="dark" :content="data.desc ? node.label + '(' + data.desc + ')' : node.label" placement="right">
- <span class="dept-tree-node">
- <i :class="iconCls(data.icon || 'folder')" style="margin-right: 5px;" v-if="showIcon"></i>
- <span>{{ node.label }}</span>
- <el-badge :value="data.desc" class="item" type="info"></el-badge>
- </span>
- </el-tooltip>
- </slot>
- </template>
- </el-tree>
- </div>
- </template>
- <script>
- export default {
- props: {
- navItems: Array,
- dataItems: Array,
- virtualRoot: String,
- showIcon: { type: Boolean, default: false },
- placeholder: String,
- showCheckbox: { type: Boolean, default: false },
- keys: Array,
- },
- data() {
- return {
- navProps: {
- children: 'children',
- label: 'name',
- },
- filter: null,
- };
- },
- methods: {
- handleCheckChange() {
- const data = this.$refs.tree.getCheckedNodes();
- this.$emit('checkchange', data);
- },
- handleNavClick(data) {
- this.$emit('selected', data && !data.isRoot ? data : null);
- },
- setCurrentKey(key) {
- this.$refs['tree'].setCurrentKey(key);
- },
- iconCls(icon) {
- if (icon && !(icon.indexOf('el-') === 0)) {
- return `naf-icons naf-icon-${icon}`;
- }
- return icon;
- },
- },
- computed: {
- treeItems() {
- if (this.filter) {
- return this.dataItems.filter(p => p.name && p.name.includes(this.filter));
- } else {
- if (this.navItems) return this.navItems;
- const items = this.dataItems || [];
- let roots = items.filter(a => !items.some(b => b.id === a.pid));
- const fetchChildren = item => {
- if (!item.path) item.path = [item.name];
- const children = items.filter(p => p.pid === item.id).map(p => fetchChildren({ ...p, parent: item, path: item.path.concat(p.name) }));
- return { ...item, children };
- };
- roots = roots.map(p => fetchChildren(p));
- if (!this.virtualRoot) {
- return roots;
- }
- // 显示虚拟根目录
- return [{ [this.navProps.label]: this.virtualRoot, children: roots, isRoot: true, icon: 'dept' }];
- }
- },
- },
- watch: {
- keys(val) {
- this.$refs.tree.setCheckedKeys(val);
- },
- },
- };
- </script>
- <style lang="less" scoped>
- .item {
- margin-top: 6px;
- margin-left: 5px;
- }
- .nav-tree {
- width: 100%;
- overflow-x: auto;
- /deep/ .el-tree-node.is-current > .el-tree-node__content {
- background-color: #409eff;
- color: white;
- .naf-icon-dian {
- display: inline;
- color: white;
- }
- }
- /deep/ .naf-icon-dian {
- display: none;
- }
- /deep/ .el-tree-node__content:hover .naf-icon-dian {
- display: inline;
- }
- .filter {
- display: block;
- position: relative;
- width: 90%;
- margin: 0 auto;
- margin-bottom: 10px;
- margin-top: 10px;
- }
- .el-tree {
- width: 100%;
- overflow: hidden;
- }
- /deep/ .dept-tree-node {
- overflow: hidden;
- display: flex;
- .el-tooltip {
- overflow: hidden;
- width: 100%;
- display: inline-grid;
- }
- }
- }
- </style>
|