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"
:node-key="'id'" :data="record.option"
:props="defaultProps" :filter-method="filterNode"
@check-change="handleCurrentChange(index)">
<template #default="{ node }">
<div v-html='highlightName(node, searchVal)'></div>
</template>
</vl-tree>
</div>
</template>
</el-option>
</el-select>
</template>
// 搜索
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
filterTree(val, index) {
this.searchVal = val
let tree = 'tree' + index
this.$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]
}
this.getList(params, index)
}
},
// 获取知识树选中值
handleCurrentChange(data, isSelect, childSelect, index) {
let tree = 'tree' + index
let nodes = this.$refs[tree].getCheckedNodes()
let arrId = []
if (nodes.length > 0) {
nodes.map(item => {
arrId.push(item.id)
})
}
let listData = this.dataSource[index].option
let 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' + index
const 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 = text
let 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 = true
await 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
})
},