选择框搜索+二级搜索名称
<template>
<el-dialog
width="65%"
class="types"
:modal="false"
title="药品类别"
:destroy-on-close="true"
:visible="typeState"
@close="closeTypeDialog"
@open="open"
>
<el-container v-loading="typeLoading">
<el-aside
width="50%"
class="classifyLeft">
<el-container>
<el-main>
<div>
<el-row :gutter="10">
<el-col :span="12">
<el-select
v-model="searchValue"
size="mini"
style="width: 100%"
clearable
placeholder="请选择"
@change="handleSearch"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-col>
<el-col :span="12">
<el-autocomplete
v-model="value"
size="mini"
style="width: 100%"
:fetch-suggestions="querySearchAsync"
placeholder="请输入内容"
@select="handleSelect"
/>
</el-col>
</el-row>
</div>
<div style="height: 70%">
<el-tree
ref="tree"
class="tree"
highlight-current
:expand-on-click-node="false"
:data="treeData"
:props="defaultProps"
:default-expanded-keys="defaultShowNodes"
:filter-node-method="filterNode"
node-key="id"
@node-click="handleNodeClick"
/>
<!-- :default-expanded-keys='' -->
</div>
</el-main>
</el-container>
</el-aside>
<el-main style="padding-left: 10px !important">
<el-container style="height: 300px">
<el-header style="height: 20px">
<label> 已添加: </label>
<span
style="float: right; font-size: 20px"
>{
{ checkList.length }}条</span
>
</el-header>
<el-main class="classifyTag">
<el-tag
v-for="tag in checkList"
:key="tag.id"
:disable-transitions="false"
size="medium"
closable
@close="removeTag(tag)"
>
{
{ tag.label }}
</el-tag>
</el-main>
</el-container>
</el-main>
</el-container>
<span
slot="footer"
class="dialog-footer">
<el-button
size="mini"
@click.stop="closeTypeDialog">取 消</el-button>
<el-button
type="primary"
size="mini"
@click.stop="searchType"
>确 定</el-button
>
</span>
</el-dialog>
</template>
<style lang="scss" scoped>
.tree {
margin-top: 10px;
height: 500px;
overflow: auto;
}
::v-deep.types {
.el-dialog__body {
height: 60vh !important;
}
.el-dialog__header {
padding: 7px;
background-color: #33adff;
.el-dialog__headerbtn {
top: 10px;
}
.el-dialog__title {
color: #fff;
font-size: 14px;
}
.el-dialog__headerbtn .el-dialog__close {
color: #fff;
margin-top: -10px;
}
}
}
#classifyTree ::v-deep .el-scrollbar__bar {
right: 0 !important;
}
.classifyLeft {
height: 100%;
padding-right: 10px;
border-right: 1px solid #ebeef5;
}
.classifyTag {
height: 100%;
width: 100%;
// margin: 10px 0 !important;
}
.classifyTag ::v-deep .el-tag {
width: 100%;
margin-bottom: 5px;
position: relative;
}
.classifyTag ::v-deep .el-tag__close {
position: absolute;
top: 6px;
right: 10px;
}
::v-deep.type .el-textarea__inner {
color: #000;
}
::v-deep.el-tree--highlight-current
.el-tree-node.is-current
> .el-tree-node__content {
background-color: #409eff;
}
</style>
import {
queryAllTree } from '@api/common_info.js';
export default {
props: {
typeState: {
type: Boolean,
default: false
},
checkList: {
type: Array,
default: () => []
}
},
data () {
return {
// 已选中的id数组
typeLoading: false,
treeData: [],
allTreeData: [],
defaultProps: {
children: 'children',
label: 'label',
value: 'label'
},
typeIdArry: [],
value: '',
searchValue: '',
options: [],
defaultShowNodes: []
};
},
watch: {
value (val) {
this.$refs.tree.filter(val);
},
treeData: {
handler () {
this.treeData.forEach((item) => {
this.defaultShowNodes.push(item.id);
});
},
deep: true
}
// searchValue (val) {
// this.$refs.tree.filter(val);
// this.handleNodeClick(val);
// }
},
methods: {
// 树扁平化
treeToFlat (treeList, flatList) {
// flatList.length > 9999 是考虑底线保护原则,出于极限保护的目的设置的,可不设或按需设置。
if (flatList.length > 9999) {
return;
}
// eslint-disable-next-line array-callback-return
treeList.map((e) => {
e.value = e.label;
flatList.push(e);
// 递归:有条件的自己调用自己,条件是 e.children.length 为真
if (e.children && e.children.length) {
this.treeToFlat(e.children, flatList);
}
});
// console.log('扁平化后:', flatList)
return flatList;
},
// 选择树
handleSearch (val) {
console.log(val);
// 选择全部或清空树把树赋值给根节点
if (!val || val === '6f06879f-dc48-11ea-a132-6c92bf99a3a6') {
this.treeData = JSON.parse(JSON.stringify(this.allTreeData));
} else {
// 选择其他项加选中;
this.treeData = this.allTreeData[0].children.filter((item) => {
return item.id === val;
});
}
this.$nextTick(() => {
// selectId:绑定的 node-key
this.handleNodeClick(this.treeData[0]);
this.$refs.tree.setCurrentKey(this.treeData[0].id);
});
this.$forceUpdate();
},
// 树可搜索 watch判断
filterNode (value, data) {
console.log(value, data);
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
// 级联搜索
querySearchAsync (queryString, cb) {
let treeArray = [];
treeArray = this.treeToFlat(this.treeData, treeArray);
const results = queryString ? treeArray.filter(this.createFilter(queryString)) : treeArray;
// 调用 callback 返回建议列表的数据
console.log(results);
cb(results);
},
createFilter (queryString) {
return (treeArray) => {
return treeArray.label.indexOf(queryString) === 0;
};
},
// 级联选择
handleSelect (val) {
console.log(val);
this.handleNodeClick(val);
this.$nextTick(() => {
// selectId:绑定的 node-key
this.$refs.tree.setCurrentKey(val.id);
});
},
// 初始化
open () {
this.typeLoading = true;
queryAllTree({
sysTag: 'kb', type: 4 }).
then((result) => {
const arr = result.data.data[0];
this.allTreeData.push(arr);
this.treeData = JSON.parse(JSON.stringify(this.allTreeData));
this.options = this.allTreeData[0].children.map((item) => {
return {
id: item.id,
label: item.label,
value: item.id
};
});
this.options.unshift({
id: '6f06879f-dc48-11ea-a132-6c92bf99a3a6',
label: '全部',
value: '6f06879f-dc48-11ea-a132-6c92bf99a3a6'
});
this.$nextTick(() => {
// selectId:绑定的 node-key
this.$refs.tree.setCurrentKey(this.treeData[0].id);
});
this.typeLoading = false;
}).
catch((err) => {
console.log(err);
});
},
// 移除
removeTag (tag) {
this.typeIdArry.filter((i) => i !== tag.id);
this.checkList.splice(this.checkList.indexOf(tag), 1);
},
// 点击树
handleNodeClick (data) {
console.log(data);
const {
id, label } = data;
const tmp = this.checkList.find((x) => x.id === id);
if (!tmp && label !== '全部') {
this.checkList.push({
label,
id
});
}
},
// 确定
searchType () {
this.typeIdArry = [];
this.typeIdArry = this.checkList.map((i) => i.label);
const finalArr = [];
this.typeIdArry.forEach((item) => {
finalArr.push(this.findPatentValue(this.allTreeData[0].children, item, 'label', 'children').join('->'));
});
console.log(finalArr);
this.$emit('searchType', finalArr.join('\n'));
},
recursiveFilter (arr, v, result) {
arr.forEach((item) => {
if (item.id === v) {
result.push(item);
} else if (item.children.length > 0) {
this.recursiveFilter(item.children, v, result);
}
});
},
//查找子节点所有的父节点
findPatentValue (array, targetId, valueKey, childrenKey) {
if (!targetId || !Array.isArray(array)) return [];
const result = [];
let valid = false;
const seek = (_array, _targetId) => {
let parentValue = '';
const up = (_array_, _targetId_, lastValue) => {
_array_.forEach((v) => {
const val = v[valueKey];
const child = v[childrenKey];
if (val === _targetId_) {
valid = true;
parentValue = lastValue;
return;
}
child?.length && up(child, _targetId_, val);
});
};
up(_array, _targetId);
if (parentValue) {
result.unshift(parentValue);
seek(_array, parentValue);
}
};
seek(array, targetId);
return valid ? [...result, targetId] : [];
},
// 关闭
closeTypeDialog () {
this.treeData = [];
this.allTreeData = [];
this.value = '';
this.searchValue = '';
this.$emit('closeDialog', {
typeIdArr: this.typeIdArry });
}
}
};