element select + tree的使用

<template slot="action1" slot-scope="text, record, index"><el-select v-model="record.tagValue" multiple placeholder="请选择":filter-method="(e) => filterTree(e, index)" filterable @remove-tag="(e) => removeTag(e, index)"@click.native="selectFocus(record, index)" ><el-option><template slot="default"><div><!-- <el-tree :data="record.option" show-checkbox node-key="id":props="defaultProps" :ref="'tree' + index":filter-node-method="filterNode"@check-change="handleCurrentChange(index)"><template #default="{ node }"><div v-html='highlightName(node,searchVal)'></div></template></el-tree> --><!-- 虚拟列表 解决后端返回数据过多,造成页面渲染卡顿问题 安装 npm install @sangtian152/virtual-tree--save在main.js中引入import VlTree from '@sangtian152/virtual-tree';import "@sangtian152/virtual-tree/lib/vl-tree.css";Vue.use(VlTree);https://sangtian152.github.io/virtual-tree/zh/demo/#method--><vl-tree :ref="'tree' + index" :show-checkbox="true":checkable="true"node-key="name" :data="record.option":props="defaultProps" :filter-method="filterNode":default-checked-keys="record.defaultCheck"@check-change="handleCurrentChange(index)"><template #default="{ node }"><div v-html='highlightName(node, searchVal)'></div></template></vl-tree></div></template></el-option></el-select>
</template>
defaultProps: {value: 'name', //绑定id ,无id绑定的namechildren: 'children',label: 'name'
},
// 搜索
filterNode(value, data) {if (!value) return true;return data.name.indexOf(value) !== -1;
},
filterTree(val, index) {this.searchVal = vallet tree = 'tree' + indexthis.$refs[tree].filter(this.searchVal);
},
// 搜索字体高亮
highlightName (item,val) {let textHtml = "";if (val) {let highlightTextList = val.split("#~~~~");let newName = item.data.name;highlightTextList.forEach((text) => {if (item.data.name.indexOf(text) > -1) {newName = newName.replaceAll(text,`<span class="minddleContent">${text}</span>`);}});textHtml += newName;} else {textHtml += item.data.name;}return textHtml;
},
// 编辑时select 点击input传对应值 获取修改列表对应的接口数据
selectFocus(val, index) {if (this.dataSource[index].name != '请输入' && this.dataSource[index].tagValue.length > 0) {let params = {subject: this.subjectId,labels: [this.dataSource[index].name]}if(this.dataSource[index].option && this.dataSource[index].option.length == 0 || this.dataSource[index].tagValue.length > 0 && !this.dataSource[index].option){this.getList(params, index)}}this.dataSource[index].defaultCheck = this.dataSource[index].tagValue //默认勾选的节点数组
},
// 获取知识树选中值
handleCurrentChange(data, isSelect, childSelect, index) {let tree = 'tree' + indexlet nodes = this.$refs[tree].getCheckedNodes()let arrId = []if (nodes.length > 0) {nodes.map(item => {arrId.push(item.id)})}let listData = this.dataSource[index].optionlet listText = this.getStructuredKeys(arrId, nodes, listData)this.dataSource[index].tagValue = listText.map(item => {return item.name})
},
// 知识树选中值递归,选中子集只展示子集,父级全选只展示父级
getStructuredKeys(keys, list, listData) {const result = [];const processNode = (nodes) => {nodes.forEach((node) => {if (keys.includes(node.id)) {result.push(node);} else {if (node.children) {const childKeys = this.getStructuredKeys(keys, list, node.children);console.log(childKeys)if (childKeys.length > 0) {result.push(...childKeys);}}}});};processNode(listData);return this.sortSelectedItems(result, list);
},
// 选中项排序
sortSelectedItems(result, list) {const SelectedItems = result.map(v => v.id)const sortList = [];list.filter(item => {if (SelectedItems.includes(item.id)) {sortList.push(item);}})return sortList
},
// 移除select-tree选中值
removeTag(tag, index) {let tree = 'tree' + indexconst checkNodes = this.$refs[tree].getCheckedNodes();const newCheckNodes = checkNodes.filter(item => {return item.name !== tag})const removeIds = [];const removeNodes = checkNodes.filter(item => {return item.name === tag});this.getNodeChildIds(removeNodes, removeIds)const checkIds = []newCheckNodes.forEach(item => {if (!removeIds.includes(item.id)) {checkIds.push(item.id);}})this.$refs[tree].setCheckedKeys(checkIds)
},
// 移除选中递归
getNodeChildIds(nodes, result) {nodes.forEach(item => {result.push(item.id)if (item.children && item.children.length > 0) {this.getNodeChildIds(item.children, result)}})
},
// 点击标签名称传参
handleOptionSelect(text, index) {this.searchVal = ''this.dataSource[index].tagValue = []this.dataSource[index].name = textlet params = {}// 数学if (this.subjectId == '1002') {if (text == '考查知识点' || text == '涉及知识点') {params = {subject: this.subjectId,labels: ['知识']}} else {params = {subject: this.subjectId,labels: [text]}}// 物理} else if (this.subjectId == '1004') {if (text == '考查知识点' || text == '涉及知识点') {params = {subject: this.subjectId,labels: ['知识点']}} else if (text == '考查考向' || text == '涉及考向') {params = {subject: this.subjectId,labels: ['考向']}} else {params = {subject: this.subjectId,labels: [text]}}// 历史} else if (this.subjectId == '1006') {if (text == '考查知识点' || text == '涉及知识点') {params = {subject: this.subjectId,labels: ['课标知识点']}} else {params = {subject: this.subjectId,labels: [text]}}// 道法} else if (this.subjectId == '1007') {if (text == '考查知识点' || text == '涉及知识点') {params = {subject: this.subjectId,labels: ['教材知识点']}} else {params = {subject: this.subjectId,labels: [text]}}} else {params = {subject: this.subjectId,labels: [text]}}this.getList(params, index) // 接口方法
},
// 接口数据
async getList(params, index = '') {this.loading = trueawait getTagsList(params).then((res => {if (params.labels) {let newJson = this.dataSource[index]newJson.option = res.data[params.labels];this.$set(this.dataSource, index, newJson) // 编辑页面数据更新,页面未更新使用this.$set更新,this.dataSource目标值 , index目标位置, newJson 赋值数据 } else {this.options = Object.keys(res.data)}this.loading = false})).catch((error) => {// this.$message.error('数据正在处理,请勿重复提交')this.loading = false})
},