文山网站建设联系电话,做一个主题的网页代码,tk网站免费,好用的磁力搜索引擎需求
PS#xff1a;写在前面#xff0c;需求想要一个Tree 形结构展示当前的组织机构#xff0c;最末层节点可以选择#xff0c;层级明确。第一选择网上npm官网或者github 找找成型的东西
element-ui Tree 没有组织结构线js-tree 好看#xff0c;但是适配Vue3 有点费劲写在前面需求想要一个Tree 形结构展示当前的组织机构最末层节点可以选择层级明确。第一选择网上npm官网或者github 找找成型的东西
element-ui Tree 没有组织结构线js-tree 好看但是适配Vue3 有点费劲Vue2 倒是还好echart Tree 感觉有点类似xmind不是想要的效果 最好的就是在element-ui Tree 加上组织连线这就是最完美的效果。
方案选择
引入element-ui Tree二次封装增加连线样式实现简单效果明显效率高。自己写一个Tree ※ 但是我选第二个能了解Tree 组件实现原理自己想要啥样的就写啥样的哈哈哈哈。
Vue 递归组件
递归自己调用自己什么时候终止没有子集就终止
// TreeWithSwitch 就是子组件
templatediv classTreeWithSwitch v-foritem in dataList :keyitem.code// 本级标题以及选择框展示div classtree_contentspan{{ item.label }}/spanvan-switch size18px v-ifitem.isLeaf v-modelitem.checked //div// 递归 判断是否有子集div classnode_childrentree-with-switch :data-listitem.children v-ifitem.children.length //div/div
/template增加样式展示层级
.TreeWithSwitch {line-height: 30px;padding-left: 20px;margin-left: 25px;.tree_content {display: flex;align-items: center;justify-content: space-between;padding-right: 10px;height: 35px;font-size: 13px;white-space: nowrap;outline: 0;position: relative;}
}通过伪类增加当前连接线样式
.TreeWithSwitch {position: relative;line-height: 30px;padding-left: 20px;margin-left: 25px;.tree_content {display: flex;align-items: center;justify-content: space-between;padding-right: 10px;height: 35px;font-size: 13px;white-space: nowrap;outline: 0;position: relative;::before {position: absolute;top: 50%;left: -19px;display: block;width: 17px;border-top: 1px dashed #43484b;content: ;}::after {content: ;border-left: 1px dashed #43484b;width: 1px;height: 30px;position: absolute;left: -21px;top: -11px;}}
}可以看到很多空缺的部分上一次绘制的是在每个层级的:before :after 绘制的横线和竖线分析缺少的部分正是当前节点子集的这部分连接线
.TreeWithSwitch {position: relative;line-height: 30px;padding-left: 20px;margin-left: 25px;:last-child {.node_children {::after {display: none;}}}.node_children {position: relative;::after {content: ;border-left: 1px dashed #43484b;position: absolute;height: 100%;left: -21px;top: -11px;}}.tree_content {display: flex;align-items: center;justify-content: space-between;padding-right: 10px;height: 35px;font-size: 13px;white-space: nowrap;outline: 0;position: relative;::before {position: absolute;top: 50%;left: -19px;display: block;width: 17px;border-top: 1px dashed #43484b;content: ;}::after {content: ;border-left: 1px dashed #43484b;width: 1px;height: 30px;position: absolute;left: -21px;top: -11px;}}
}5. 但是可以发现所有的Tree的最外层是没有margin-left:20px 的也没有上图的多余的部分那怎么办呢找了下ElementUI tree 的源码他把第一层级拿出来了然后才是递归组件OK那我们在封装一个Tree 组件
# Tree 组
templatediv classTree v-foritem in dataListsecond-title :titleitem.label /tree-with-switch v-ifitem.children :data-listitem.children //div
/templatescript setup langts
import type TreeItem from /components/public/Tree/TreeItem;
import SecondTitle from /components/public/appTitle/SecondTitle.vue;
import TreeWithSwitch from /components/public/Tree/TreeWithSwitch.vue;const props defineProps({dataList: {type: ArrayTreeItem,required: true}
});
/scriptstyle scoped langless
.SecondTitle {margin-left: 5px;
}
/style OK写到这里基本上样式问题已经解决了接下来
最后一步用你的组件的时候如果获取那些是选中的节点如何获取
PS子集不处理事件无限向上抛出最后有父级处理。
# TreeWithSwitch
templatediv classTreeWithSwitch v-foritem in dataList :keyitem.codediv classtree_contentspan{{ item.label }}/span// 增加选中事件van-switch size18px v-ifitem.isLeaf v-modelitem.checked changechooseTreeItem(item) //div// 子集选中事件div classnode_childrentree-with-switch :data-listitem.children v-ifitem.children.length chooseTreeItemchooseChildrenItem//div/div
/templatescript setup langts
import type TreeItem from /components/public/Tree/TreeItem;defineProps({dataList: {type: ArrayTreeItem,required: true}
});
// 子集向上抛出事件
const emits defineEmits([chooseTreeItem]);
const chooseTreeItem (item: TreeItem) {emits(chooseTreeItem, item);
};
// 子集的子集继续向上排除这里就是逐级传递的
const chooseChildrenItem (item: TreeItem) {chooseTreeItem(item);
};
/scriptTree 组件
templatediv classTree v-foritem in dataListsecond-title :titleitem.label /// 增加绑定选中事件tree-with-switch v-ifitem.children :data-listitem.children chooseTreeItemchooseTreeItem //div
/templatescript setup langts
import type TreeItem from /components/public/Tree/TreeItem;
import SecondTitle from /components/public/appTitle/SecondTitle.vue;
import TreeWithSwitch from /components/public/Tree/TreeWithSwitch.vue;
import { ref } from vue;const props defineProps({dataList: {type: ArrayTreeItem,required: true},// 定义v-model绑定的参数chooseItemList: {type: [],required: false}
});
// 保存全部选中的节点
const selectedTreeNode ref([]);
// 值更新抛出事件
const emits defineEmits([update:chooseItemList]);
const chooseTreeItem (item: TreeItem) {// 节点是否选中选中数组新增取消选中数组删除if (item.checked) {selectedTreeNode.value.push(item.code);} else {let index selectedTreeNode.value.indexOf(item.code);if (index -1) {selectedTreeNode.value.splice(index, 1);}}// 绑定值更新emits(update:chooseItemList, selectedTreeNode.value);
};
/script
调用组件
// :data-list Tree 的数据
// v-model:chooseItemList 选中的值
tree :data-listhiddenItemList v-model:chooseItemListchooseHiddenItemList /