<template>
<page-header-wrapper>
<a-row type="flex" justify="space-around">
<a-col :xl="7" :lg="24" style="border: 1px solid rgba(0, 0, 0, 0.5); box-shadow: 0px 0.5px 10px #888888">
<a-input-search
v-model="searchStr"
placeholder="请搜索公司名称"
style="width: 100%"
@search="onSearch"
></a-input-search>
<!-- selectedKeys是选中项key的集合,expandedKeys是展开项key的集合 -->
<a-tree
v-model="checkedKeys"
:treeData="treeData"
:selectedKeys="selectedKeys"
:expandedKeys="expandedKeys"
@expand="onExpand"
:autoExpandParent="autoExpandParent"
:replaceFields="replaceFields"
@select="onSelect"
style="height: 70vh; overflow-y: auto"
>
<template slot="title1" slot-scope="{ name }" style="display: flex; justify-content: space-between">
<span
v-html="name.replace(new RegExp(searchValue, 'g'), '<span style=color:#f50>' + searchValue + '</span>')"
></span>
<a-button type="link" style="float: right" size="small" @click="showModal()">公司详情</a-button>
</template>
<template
slot="title"
slot-scope="{ name }"
style="display: flex; justify-content: space-between; width: 100%"
>
<span
v-html="name.replace(new RegExp(searchValue, 'g'), '<span style=color:#f50>' + searchValue + '</span>')"
></span>
</template>
</a-tree>
<!-- 公司详情模态框 -->
<a-modal v-model="visible" :title="computedname">
<!-- 自定义页脚按钮 -->
<template slot="footer">
<a-button key="submit" type="primary" @click="handleOk">返回</a-button>
</template>
<p>姓名: {
{ fname == null ? '纯爱战神爱看动漫' : fname }}</p>
<p>手机号: {
{ fphone == null ? '155xxxxxxxx' : fphone }}</p>
<p>社会统一代码: {
{ code == null ? '12345656632412342345' : code }}</p>
<p>企业公章号码: {
{ seal == null ? '1234234134134134' : seal }}</p>
<p>账号:{
{ lvdao_name == null ? '123456' : lvdao_name }}</p>
<p>密码:{
{ lvdao_pwd == null ? '123456' : lvdao_pwd }}</p>
<div style="text-align: center">
<p>执照副本</p>
<div><img style="width: 240px" :src="business" alt="" /></div>
<!-- <div><img style="width: 240px" :src="business==''?'@/assets/logo.png':business" alt="" /></div> -->
</div>
<div style="text-align: center">
<p>许可证</p>
<div><img style="width: 240px" :src="certificates" alt="" /></div>
</div>
</a-modal>
</a-col>
</a-row>
</page-header-wrapper>
</template>
<script>
let treeData = [
{
name: '五等份的花架',
key: '五等份的花架',
scopedSlots: { title: 'title1' }, //有此属性的都会被装上插槽名为title的插槽
children: [
{
name: '只能选一个',
key: '0-0-0',
scopedSlots: { title: 'title' },
children: [
{ name: '一花 13388888888', key: '一花 13388888888', scopedSlots: { title: 'title' } },
{ name: '二乃 13388888888', key: '二乃 13388888888', scopedSlots: { title: 'title' } },
{ name: '三玖 13388888888', key: '三玖 13388888888', scopedSlots: { title: 'title' } },
{ name: '四叶 13388888888', key: '四叶 13388888888', scopedSlots: { title: 'title' } },
{ name: '五月 13388888888', key: '五月 13388888888', scopedSlots: { title: 'title' } }
]
}
]
},
{
name: '我的青春物语果然有问题',
key: '我的青春物语果然有问题',
scopedSlots: { title: 'title1' },
children: [
{
name: '大老师自爆',
key: '1-0-0',
scopedSlots: { title: 'title' },
children: [
{ name: '雪乃 13388888888', key: '雪乃 13388888888', scopedSlots: { title: 'title' } },
{ name: '团子 13388888888', key: '团子 13388888888', scopedSlots: { title: 'title' } },
{ name: '一色 13388888888', key: '一色 13388888888', scopedSlots: { title: 'title' } },
{ name: '平冢静 13388888888', key: '平冢静 13388888888', scopedSlots: { title: 'title' } }
]
}
]
},
{
name: '青春猪头少年不可能梦见兔女郎学姐',
key: '青春猪头少年不可能梦见兔女郎学姐',
scopedSlots: { title: 'title1' },
children: [
{
name: '麻衣姐姐天下第一',
key: '2-0-0',
scopedSlots: { title: 'title' },
children: [
{ name: '李白 13388888888', key: '李白 13388888888', scopedSlots: { title: 'title' } },
{ name: '杜甫 13388888888', key: '杜甫 13388888888', scopedSlots: { title: 'title' } },
{ name: '王维 13388888888', key: '王维 13388888888', scopedSlots: { title: 'title' } },
{ name: '白居易 13388888888', key: '白居易 13388888888', scopedSlots: { title: 'title' } }
]
}
]
},
{
name: '路人女主养成计划',
key: '路人女主养成计划',
scopedSlots: { title: 'title1' },
children: [
{
name: '授权子公司',
key: '3-0-0',
scopedSlots: { title: 'title' },
children: [
{ name: '学姐 13444433888', key: '165156165', scopedSlots: { title: 'title' } },
{ name: '双马尾 13354648588', key: '89456541564', scopedSlots: { title: 'title' } },
{ name: '加藤惠 13123132288', key: '65465', scopedSlots: { title: 'title' } }
]
}
]
}
];
export default {
data() {
return {
replaceFields:{title:'name'},
expandedKeys: [],
backupsExpandedKeys: [],
autoExpandParent: false,
checkedKeys: [],
selectedKeys: [],
searchValue: '',
treeData,
searchStr: ''
};
},
methods: {
onSearch(){
var vm=this;
//添加这行代码是为了只点击搜索才触发
vm.searchValue = vm.searchStr;
//如果搜索值为空,则不展开任何项,expandedKeys置为空
//如果搜索值不位空,则expandedKeys的值要为搜索值的父亲及其所有祖先
if(vm.searchValue === ''){
vm.expandedKeys = [];
}else{
//首先将展开项与展开项副本置为空
vm.expandedKeys = [];
vm.backupsExpandedKeys = [];
//获取所有存在searchValue的节点
let candidateKeysList = vm.getkeyList(vm.searchValue,vm.treeData,[]);
//遍历满足条件的所有节点
candidateKeysList.map(
item=>{
//获取每个节点的母亲节点
var key=vm.getParentKey(item,vm.treeData);
//当item是最高一级,父key为undefined,将不放入到数组中
//如果母亲已存在于数组中,也不放入到数组中
if(key && !vm.backupsExpandedKeys.some(item=>item===key))
vm.backupsExpandedKeys.push(key);
}
)
let length=this.backupsExpandedKeys.length;
for(let i=0;i<length;i++){
vm.getAllParentKey(vm.backupsExpandedKeys[i],vm.treeData)
}
vm.expandedKeys = vm.backupsExpandedKeys.slice();
}
},
//获取节点中含有value的所有key集合
getkeyList(value,tree,keyList){
//遍历所有同一级的树
for(let i=0;i<tree.length;i++){
let node = tree[i];
//如果该节点存在value值则push
if(node.name.indexOf(value)>-1){
keyList.push(node.key);
}
//如果拥有孩子继续遍历
if(node.children){
this.getkeyList(value,node.children,keyList);
}
}
//因为是引用类型,所有每次递归操作的都是同一个数组
return keyList;
},
//该递归主要用于获取key的父亲节点的key值
getParentKey(key,tree){
let parentKey,temp;
//遍历同级节点
for(let i=0;i<tree.length;i++){
const node=tree[i];
if(node.children){
//如果该节点的孩子中存在该key值,则该节点就是我们要找的父亲节点
//如果不存在,继续遍历其子节点
if(node.children.some(item=>item.key===key)){
parentKey = node.key;
}else if(temp=this.getParentKey(key,node.children)){
//parentKey = this.getParentKey(key,node.children)
//改进,避免二次遍历
parentKey = temp;
}
}
}
return parentKey;
},
//获取该节点的所有祖先节点
getAllParentKey(key,tree){
var parentKey;
if(key){
//获得父亲节点
parentKey = this.getParentKey(key,tree);
if(parentKey){
//如果父亲节点存在,判断是否已经存在于展开列表里,不存在就进行push
if(!this.backupsExpandedKeys.some(item=>item===parentKey)){
this.backupsExpandedKeys.push(parentKey);
}
//继续向上查找祖先节点
this.getAllParentKey(parentKey,tree);
}
}
},
onExpand(expandedKeys) {
//用户点击展开时,取消自动展开效果
this.expandedKeys = expandedKeys;
this.autoExpandParent = false;
},
onCheck(checkedKeys) {
console.log('onCheck', checkedKeys);
this.checkedKeys = checkedKeys;
},
onSelect(selectedKeys, info) {
console.log('onSelect', info);
this.selectedKeys = selectedKeys;
},
},
};
</script>
<style lang="less" scoped>
::v-deep .ant-tree-node-content-wrapper {
display: contents !important;
}
</style>
此demo复制过去就能使用,但是发起网络请求并处理数据后有时候会出现搜索无法展开的情况。此时需要在处理数据时处理异步操作,下面是我当时的解决办法
其中使用 async 与 await 解决异步
?为判断内部是否有后面的参数
??为如果值为 空 或者 null 就执行后续代码
async getComputeData() {
//获取公司列表
const res = await this.$mApi.getNodeAction('/company/list', { pageSize: 100000, pageNo: 1 });
this.companyList = res.result.data;
// console.log('接口获取的公司列表', res.result.data);
//将数组进行修改并push到 treeData 里面
this.treeData = [];
for (const element of res.result.data) {
const { result = {} } = await this.$mApi.getNodeAction('/team/company', { id: element.id });
if (!result.authCompanyList.length) {
this.treeData.push({
// name: element.name,
name: element?.name ?? '暂时公司没名字' ,
key: element.id,
scopedSlots: { title: 'title1' }
});
// this.generateList(res.result.data); // 必须初始化树结构时执行,否则搜索结果不展开
} else {
//遍历子公司
let childrenList = [];
for (const item of result.authCompanyList) {
childrenList.push({
name: item.realname || 'haha',
key: item.company_id,
scopedSlots: { title: 'title' }
});
}
this.treeData.push({
// name:element.name,
name: element?.name ?? '暂时公司没名字' ,
key: element.id,
scopedSlots: { title: 'title1' },
children: [
{
name: '授权子公司',
key: element.name + element.id,
scopedSlots: { title: 'title' },
children: childrenList
}
]
});
}
}
},
效果展示