Vue AntDesign可搜索的树(只展示搜索结果并展开)


前言

项目中用到的树结构数据太多,领导觉得AntDesign中把搜索到关键字的数据层级展开也不是很直观,所以要求只展示搜索到的数据并且展开层级。

一、dom结构

就是去antDesign 复制可搜索树结构就可以了,我这里还加了输入即刻检索

<a-input-search style="margin-bottom: 8px" placeholder="Search" v-model="searchVal" @change="searchOnChange" @search="onSearch" />
    <a-tree
      :expanded-keys="iExpandedKeys"
      :auto-expand-parent="autoExpandParent"
      :tree-data="showData"
      @expand="onExpand"
      :replace-fields="{children:'children', key:'id', value: 'id', title: 'label'}"
    >
      <template slot="label" slot-scope="{ label}">
        <span v-if="label.indexOf(searchValue) > -1">
          {{ label.substr(0, label.indexOf(searchValue)) }}
          <span style="color: #f50">{{ searchValue }}</span>
          {{ label.substr(label.indexOf(searchValue) + searchValue.length) }}
        </span>
        <span v-else>{{ label}}</span>
      </template>
    </a-tree>

二、保存一份完整数据

1.定义数据

在data中定义两个变量,一个showData(用于树的真实展示数据),一个defaultData(全部数据的备份,用于清除搜索条件时展示全部数据)

data () {
	return {
		showData: [],
		defaultData: [],
		expandedKeys:[],
		searchVal: "",
		searchValue: "",
		iExpandedKeys: [],
		autoExpandParent: true,
	}
}

2.存数据

mounted () {
	this.getTreeData ();
},
methods: {
	getTreeData () {
		this.showData = [];
		this.defaultData = [];
		//调用获取数据的接口
		getTreeData().then((res) => {
			for (let i = 0; i < res.result.length; i++) {
              let temp = res.result[i]
              this.defaultData.push(JSON.parse(JSON.stringify(temp)))
              this.showData = [...this.defaultData];
              this.recursionData(this.defaultData);//将每一层数据都赋上title的slot,以高亮显示搜索字段
              this.setThisExpandedKeys(temp)
              // console.log(temp.id)
            }
		})
	},
	recursionData (node) {
        node.forEach(item => {
          item.scopedSlots = { title: 'label' }
          if (item.children && item.children.length) {
            this.recursionData(item.children)
          }
        })
      },
	setThisExpandedKeys(node) {
        //只展开一级目录
        if (node.children && node.children.length > 0) {
          this.iExpandedKeys.push(node.id)
          //下方代码放开注释则默认展开所有节点
          
          // for (let a = 0; a < node.children.length; a++) {
          //   this.setThisExpandedKeys(node.children[a])
          // }
        }
    },
    onExpand(expandedKeys) {
        this.iExpandedKeys = expandedKeys
        this.autoExpandParent = false
    },
}

三、定义搜索方法,删除未匹配数据

methods: {
      searchOnChange () {
        this.showData= [...this.defaultData];
        if (this.searchVal) {
          this.onSearch(this.searchVal);
        } else {
          this.searchValue = "";
          this.iExpandedKeys = [this.showData[0].id];
        }
      },
      onSearch(val){
          const value = val
          this.searchValue = value
          if (value != '') {
            let treeData = JSON.parse(JSON.stringify(this.showData));
            // 删除四级中未匹配到的数据
            this.deleteTreedata(treeData, val, 4);
            // 删除三级数据中未匹配到的数据
            this.deleteTreedata(treeData, val, 3);
            // 删除二级数据中未匹配到的数据
            this.deleteTreedata(treeData, val, 2);
            this.showData= [...treeData];
            // 展开所有树数据 
            this.expandAll(this.showData);
          } else {
              this.iExpandedKeys = [this.showData[0].id];
          }
      },
      deleteTreedata (node, val, level) {
      	//这里注意数组一定要从后面对比删除,否则数组从前面删了以后,顺序就乱掉,就只能删第一个了
        for (let len = node.length - 1; len >= 0; len--) {
          if (node[len].children && node[len].children.length) {
            this.deleteTreedata(node[len].children, val, level)
          } else {
            if (node[len].level == level) {
              let str = node[len].label;
              if (str.indexOf(val) < 0) {
                node.splice(len, 1);
              }
            }
          }
        }
      },
      expandAll (node) {
        console.log('nodenode', node);
        node.forEach(item => {
          if (item.children && item.children.length) {
            this.iExpandedKeys.push(item.id)
            this.expandAll(item.children)
          }
        })
      },
}

测试数据

随便写了一个测试数据,可以试一下,大概就是这个格式

testData: [
   {
     id: '1',
     label: '中国',
     level: '1',
     children: [
       {
         id: '2',
         label: '山东',
         level: '2',
         children: [
           {
             id: '4',
             label: '济南',
             level: '3',
             children: [
               {
                 id: '5',
                 label: '槐荫区',
                 level: '4'
               },
               {
                 id: '6',
                 label: '市中区',
                 level: '4'
               },
               {
                 id: '7',
                 label: '历城区',
                 level: '4'
               },
               {
                 id: '8',
                 label: '历下区',
                 level: '4'
               },
             ]
           }
         ]
       },
       {
         id: '3',
         label: '河北',
         level: '2',
         children: [
           {
             id: '9',
             label: '廊坊',
             level: '3'
           }
         ]
       }
     ]
   }
 ],

重新改了一点东西,上传了git,简单的小demo

地址 :https://gitee.com/huangcuiying/antd-tree

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Vue Ant Design 中,可以使用 `expandable` 属性来实现 Table 行的展开和收起。具体实现步骤如下: 1. 在 Table 组件中设置 `expandable` 属性为一个对象,该对象包含两个属性:`expandedRowRender` 和 `onExpand`。 ```html <template> <a-table :columns="columns" :data-source="data" :expandable="expandable"> </a-table> </template> <script> export default { data() { return { columns: [...], data: [...], expandable: { expandedRowRender: (record) => { // 返回展开行的内容 }, onExpand: (expanded, record) => { // expanded 为该行是否展开的状态,record 为当前行的数据 } } } } } </script> ``` 2. 在 `expandedRowRender` 属性中定义展开行的内容。该属性需要一个函数作为值,该函数接收一个参数 `record`,表示当前行的数据。在该函数中返回需要展开的内容。 ```html <template> <a-table :columns="columns" :data-source="data" :expandable="expandable"> </a-table> </template> <script> export default { data() { return { columns: [...], data: [...], expandable: { expandedRowRender: (record) => { // 返回展开行的内容 return ( <p>{ record.description }</p> ) }, onExpand: (expanded, record) => { // expanded 为该行是否展开的状态,record 为当前行的数据 } } } } } </script> ``` 3. 在 `onExpand` 属性中定义展开和收起的事件。该属性需要一个函数作为值,该函数接收两个参数:`expanded` 和 `record`,分别表示该行是否展开的状态和当前行的数据。 ```html <template> <a-table :columns="columns" :data-source="data" :expandable="expandable"> </a-table> </template> <script> export default { data() { return { columns: [...], data: [...], expandable: { expandedRowRender: (record) => { // 返回展开行的内容 return ( <p>{ record.description }</p> ) }, onExpand: (expanded, record) => { // expanded 为该行是否展开的状态,record 为当前行的数据 console.log(expanded, record) } } } } } </script> ``` 完成上述步骤后,即可实现 Vue Ant Design Table 行的展开和收起。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值