123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- <template>
- <div class="tree-container">
- <el-row :gutter="20">
- <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
- <el-divider content-position="left">常规树</el-divider>
- <el-input v-model="filterText" placeholder="输入关键字过滤" />
- <el-tree
- ref="demoTree"
- :data="data2"
- :default-checked-keys="defaultCheckedKeys"
- :default-expanded-keys="defaultExpendedKeys"
- :expand-on-click-node="false"
- :filter-node-method="filterNode"
- :highlight-current="true"
- :props="defaultProps"
- class="vab-filter-tree"
- node-key="id"
- show-checkbox
- @check="checkNode"
- @node-click="nodeClick"
- @node-collapse="nodeCollapse"
- @node-expand="nodeExpand"
- >
- <template #defalut="{ node, data }" class="vab-custom-tree-node">
- <span class="vab-tree-item">
- <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
- {{ node.label }}
- </span>
- <span class="vab-tree-options">
- <a
- v-if="node.data.rank !== 4"
- class="vab-tree-btn"
- title="添加"
- @click="() => append(node, data, 0)"
- >
- <i class="el-icon-plus"></i>
- </a>
- <a
- class="vab-tree-btn"
- title="编辑"
- @click="() => edit(node, data, 1)"
- >
- <i class="el-icon-edit"></i>
- </a>
- <a
- v-if="node.data.rank !== 1"
- class="vab-tree-btn"
- title="刪除"
- @click="() => remove(node, data)"
- >
- <i class="el-icon-delete"></i>
- </a>
- </span>
- </template>
- </el-tree>
- </el-col>
- <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
- <el-divider content-position="left">懒加载树</el-divider>
- <el-input
- v-model.lazy="keyW"
- :value="keyW"
- class="input-with-select"
- placeholder="请输入内容"
- @keyup.enter.native="showTreeList"
- ></el-input>
- <div v-show="isShow" class="blur-tree">
- <el-tree
- ref="treeFilter"
- :data="filterDevLlist"
- :expand-on-click-node="false"
- :props="defaultProps"
- class="vab-filter-tree"
- default-expand-all
- highlight-current
- node-key="indexCode"
- @node-click="nodeClick"
- >
- <template #defalut="{ node }" class="vab-custom-tree-node">
- <span class="vab-tree-item">
- <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
- {{ node.label }}
- </span>
- <span class="vab-tree-options">
- <a
- v-if="node.data.rank !== 4"
- class="vab-tree-btn"
- title="添加"
- >
- <i class="el-icon-plus"></i>
- </a>
- <a class="vab-tree-btn" title="编辑">
- <i class="el-icon-edit"></i>
- </a>
- <a
- v-if="node.data.rank !== 1"
- class="vab-tree-btn"
- title="刪除"
- >
- <i class="el-icon-delete"></i>
- </a>
- </span>
- </template>
- </el-tree>
- </div>
- <div v-show="!isShow" class="el-tree-wrap">
- <el-tree
- ref="tree"
- v-loading="loading"
- :expand-on-click-node="false"
- :load="loadNode"
- :props="defaultProps"
- class="vab-filter-tree"
- highlight-current
- lazy
- node-key="indexCode"
- @node-click="nodeClick"
- >
- <template #defalut="{ node }" class="vab-custom-tree-node">
- <span class="vab-tree-item">
- <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
- {{ node.label }}
- </span>
- <span class="vab-tree-options">
- <!-- <a v-if="node.data.rank !== 4" class="vab-tree-btn" title="添加""><i class="el-icon-plus"></i></a> -->
- <a class="vab-tree-btn" title="编辑">
- <i class="el-icon-edit"></i>
- </a>
- <a
- v-if="node.data.rank !== 1"
- class="vab-tree-btn"
- title="刪除"
- >
- <i class="el-icon-delete"></i>
- </a>
- </span>
- </template>
- </el-tree>
- </div>
- </el-col>
- <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
- <el-divider content-position="left">单选树</el-divider>
- <el-select
- ref="singleTree"
- v-model="singleSelectTreeVal"
- class="vab-tree-select"
- clearable
- popper-class="select-tree-popper"
- value-key="id"
- @clear="selectTreeClearHandle('single')"
- >
- <el-option :value="singleSelectTreeKey">
- <el-tree
- id="singleSelectTree"
- ref="singleSelectTree"
- :current-node-key="singleSelectTreeKey"
- :data="selectTreeData"
- :default-expanded-keys="selectTreeDefaultSelectedKeys"
- :highlight-current="true"
- :props="selectTreeDefaultProps"
- node-key="id"
- @node-click="selectTreeNodeClick"
- >
- <template #defalut="{ node }" class="vab-custom-tree-node">
- <span class="vab-tree-item">{{ node.label }}</span>
- </template>
- </el-tree>
- </el-option>
- </el-select>
- </el-col>
- <el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
- <el-divider content-position="left">多选树</el-divider>
- <el-select
- v-model="multipleSelectTreeVal"
- class="vab-tree-select"
- clearable
- collapse-tags
- multiple
- popper-class="select-tree-popper"
- @change="changeMultipleSelectTreeHandle"
- @clear="selectTreeClearHandle('multiple')"
- @remove-tag="removeSelectTreeTag"
- >
- <el-option :value="multipleSelectTreeKey">
- <el-tree
- id="multipleSelectTree"
- ref="multipleSelectTree"
- :current-node-key="multipleSelectTreeKey"
- :data="selectTreeData"
- :default-checked-keys="selectTreeDefaultSelectedKeys"
- :default-expanded-keys="selectTreeDefaultSelectedKeys"
- :highlight-current="true"
- :props="selectTreeDefaultProps"
- node-key="id"
- show-checkbox
- @check="multipleSelectTreeCheckNode"
- ></el-tree>
- </el-option>
- </el-select>
- </el-col>
- </el-row>
- <!--添加/编辑节点弹框-------------------start-->
- <el-dialog
- :title="dialogTitle"
- :visible.sync="treeDialogVisible"
- class="tree-operate-dialog"
- width="400px"
- @close="treeDialogVisible = false"
- >
- <el-form ref="treeForm" :model="treeForm">
- <el-form-item label="节点名称" required>
- <el-input v-model="treeForm.name"></el-input>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button @click="treeDialogVisible = false">取 消</el-button>
- <el-button type="primary" @click="saveTree">确 定</el-button>
- </div>
- </el-dialog>
- <!--添加/编辑节点弹框-------------------end-->
- </div>
- </template>
- <script>
- import { getTreeList } from "@/api/tree";
- export default {
- name: "Tree",
- data() {
- return {
- dialogTitle: "添加节点",
- treeFlag: 0,
- treeDialogVisible: false,
- treeForm: {
- id: "",
- name: "",
- },
- checkNodeKeys: [],
- filterText: "",
- data2: [],
- defaultProps: {
- children: "children",
- label: "name",
- },
- defaultExpendedKeys: [],
- defaultCheckedKeys: [],
- loading: true,
- keyW: "",
- filterDevLlist: [],
- isShow: false,
- updateTree: true,
- /* 单选树-多选树---------开始 */
- selectLevel: 4, // 树可选叶子level等级
- singleSelectTreeVal: "", //单选树默认label值
- singleSelectTreeKey: "", //单选树默认key值
- selectTreeData: [], //单选树的值
- selectTreeDefaultSelectedKeys: [], //单选树默认展开的key值数组
- selectTreeDefaultProps: {
- children: "children",
- label: "name",
- },
- multipleSelectTreeVal: [], //多选树默认label值
- multipleSelectTreeKey: "", //多选树默认key值
- /* 单选树-多选树---------结束 */
- };
- },
- watch: {
- filterText(val) {
- this.$refs.demoTree.filter(val);
- },
- },
- mounted() {
- this.$nextTick(() => {
- this.getTreeListFuc(1);
- this.setCheckedKeys();
- // 初始化单选树
- this.initSingleTree("single");
- // 初始化多选树
- this.initSingleTree("multiple");
- });
- },
- methods: {
- // 树level小于n级展开方法
- openTree(treeData, n) {
- const each = (data) => {
- data.forEach((e) => {
- if (e.rank <= n) {
- this.defaultExpendedKeys.push(e.id);
- }
- if (e.children.length > 0) {
- each(e.children);
- }
- });
- };
- each(treeData);
- },
- // 获取tree数据
- async getTreeListFuc(flag) {
- const { data } = await getTreeList();
- this.data2 = data;
- if (flag) {
- this.openTree(this.data2, 2);
- }
- },
- // 节点过滤操作
- filterNode(value, data) {
- if (!value) return true;
- return data.name.indexOf(value) !== -1;
- },
- // 添加节点操作
- append(node, data, flag) {
- this.treeFlag = flag;
- this.dialogTitle = "添加节点";
- this.treeForm = {
- id: "",
- name: "",
- };
- this.treeDialogVisible = true;
- },
- // 编辑节点操作
- edit(node, data, flag) {
- this.treeFlag = flag;
- this.dialogTitle = "编辑节点";
- this.treeForm = {
- id: data.id,
- name: data.name,
- };
- this.treeDialogVisible = true;
- },
- // 删除节点操作
- remove(node, data) {
- this.$baseConfirm("你确定要删除该节点?", null, async () => {
- const { msg } = getTreeList();
- this.$baseMessage(msg, "success");
- this.getTreeListFuc(0);
- });
- },
- // 保存添加和编辑
- saveTree() {
- this.$refs.treeForm.validate(async (valid) => {
- if (valid) {
- const { msg } = await getTreeList();
- this.$baseMessage(msg, "success");
- this.treeDialogVisible = false;
- this.getTreeListFuc(0);
- }
- });
- },
- // 设置节点选中
- setCheckedKeys() {
- this.$refs.demoTree.setCheckedKeys([1]);
- },
- // 点击叶子节点
- nodeClick(data, node, el) {},
- // 节点选中操作
- checkNode(data, node, el) {
- this.checkNodeKeys = node.checkedKeys;
- },
- // 节点展开操作
- nodeExpand(data, node, el) {
- this.defaultExpendedKeys.push(data.id);
- },
- // 节点关闭操作
- nodeCollapse(data, node, el) {
- this.defaultExpendedKeys.splice(
- this.defaultExpendedKeys.findIndex((item) => item.id === data.id),
- 1
- );
- },
- async loadNode(node, resolve) {
- if (node.level === 0) {
- const { data } = await getTreeList();
- this.loading = false;
- return resolve(data);
- } else {
- const { data } = await getTreeList();
- return resolve(res.data);
- }
- },
- //懒加载树输入框筛选方法
- async showTreeList(value) {
- if (typeof value === "string") {
- this.keyW = value.trim();
- }
- if (this.keyW.length !== 0) {
- // 请求后台返回查询结果
- let treeOption = {};
- treeOption = {
- keyWord: this.keyW,
- };
- const { data } = await getTreeList();
- this.filterDevLlist = data;
- this.isShow = true;
- } else {
- this.isShow = false;
- }
- },
- /* 单选/多选树方法-------------------开始 */
- // 初始化单选树的值
- async initSingleTree(treeType) {
- const { data } = await getTreeList();
- this.selectTreeData = data;
- this.$nextTick(() => {
- this.selectTreeDefaultSelectedKeys = this.singleSelectTreeKey.split(
- ","
- ); // 设置默认展开
- if (treeType == "single") {
- //单选树
- this.$refs.singleSelectTree.setCurrentKey(this.singleSelectTreeKey); // 设置默认选中
- } else {
- // 多选树
- this.$refs.multipleSelectTree.setCheckedKeys(
- this.selectTreeDefaultSelectedKeys
- );
- }
- });
- },
- // 清除单选树选中
- selectTreeClearHandle(type) {
- this.selectTreeDefaultSelectedKeys = [];
- this.clearSelected();
- if (type == "single") {
- this.singleSelectTreeVal = "";
- this.singleSelectTreeKey = "";
- this.$refs.singleSelectTree.setCurrentKey(""); // 设置默认选中
- } else {
- this.multipleSelectTreeVal = [];
- this.multipleSelectTreeKey = "";
- this.$refs.multipleSelectTree.setCheckedKeys([]);
- }
- },
- /* 清空选中样式 */
- clearSelected() {
- const allNode = document.querySelectorAll(
- "#singleSelectTree .el-tree-node"
- );
- allNode.forEach((element) => element.classList.remove("is-current"));
- },
- // select多选时移除某项操作
- removeSelectTreeTag(val) {
- const stack = JSON.parse(JSON.stringify(this.selectTreeData));
- while (stack.length) {
- const curr = stack.shift();
- if (curr.name == val) {
- return this.$refs.multipleSelectTree.setChecked(curr.id, false);
- }
- if (curr.children && curr.children.length) {
- stack.unshift(...curr.children);
- }
- }
- },
- changeMultipleSelectTreeHandle(val) {},
- // 点击叶子节点
- selectTreeNodeClick(data, node, el) {
- if (data.rank >= this.selectLevel) {
- this.singleSelectTreeVal = data.name;
- this.singleSelectTreeKey = data.id;
- this.$refs.singleTree.blur();
- }
- },
- // 节点选中操作
- multipleSelectTreeCheckNode(data, node, el) {
- const checkedNodes = this.$refs.multipleSelectTree.getCheckedNodes();
- const keyArr = [];
- const valueArr = [];
- checkedNodes.forEach((item) => {
- if (item.rank >= this.selectLevel) {
- keyArr.push(item.id);
- valueArr.push(item.name);
- }
- });
- this.multipleSelectTreeVal = valueArr;
- this.multipleSelectTreeKey = keyArr.join(",");
- },
- /* 单选/多选树方法-------------------结束 */
- },
- };
- </script>
|