案例下載:https://gitee.com/tudoumlp/just1.git (vue-ele-demo)
在項目中,會遇到樹節點的搜索,中文和英文搜索,以及搜索到父節點匹配的時候同步顯示該父節點下所有的子節點,搜索到子節點匹配的時候同步顯示該子節點的父節點。話不多說,以下是代碼:
首先是組件部分:
<template>
<el-popover placement="bottom-start" trigger="click" style="width:100%;" v-model="cdListVisible"> <el-tree :data="cdList" :props="{ label: 'name', children: 'children' }" node-key="id" ref="cdListTree" :filter-node-method="filterNodeTree" @current-change="currentHandle"> </el-tree> <template> <el-input slot="reference" v-model="dataForm.parentName" @input="filterInput" placeholder="設備樹"></el-input> </template> </el-popover>
</template>
:data="cdList"是請求回來的樹數據
:filter-node-method="filterNodeTree" 自定義過濾方法(重點)
@current-change="currentHandle" 當前樹節點選中事件(可忽略,做賦值操作)
@input="filterInput" 輸入信息觸發過濾事件(重要)
接下來是事件部分:
filterInput () {
//調用el-tree的filter方法,觸發條件過濾,並將當前輸入的信息傳遞到事件內部.
this.$refs.cdListTree.filter(this.dataForm.parentName) },
// 調用tree過濾方法 中文英過濾 filterNodeTree (value, data, node) { if (!value) {
//如果數據為空,則返回true,顯示所有的數據項 node.expanded = false return true } // 查詢列表是否有匹配數據,將值小寫,匹配英文數據 let val = value.toLowerCase() return this.chooseNode(val, data, node) // 調用過濾二層方法 },
// 過濾父節點 / 子節點 (如果輸入的參數是父節點且能匹配,則返回該節點以及其下的所有子節點;如果參數是子節點,則返回該節點的父節點。name是中文字符,enName是英文字符.
chooseNode (value, data, node) {
if (data.name.indexOf(value) !== -1 || data.enName.indexOf(value) !== -1) { return true } const level = node.level // 如果傳入的節點本身就是一級節點就不用校驗了 if (level === 1) { return false } // 先取當前節點的父節點 let parentData = node.parent // 遍歷當前節點的父節點 let index = 0 while (index < level - 1) { // 如果匹配到直接返回,此處name值是中文字符,enName是英文字符。判斷匹配中英文過濾 if (parentData.data.name.indexOf(value) !== -1 || parentData.data.enName.indexOf(value) !== -1) { return true } // 否則的話再往上一層做匹配 parentData = parentData.parent index++ } // 沒匹配到返回false return false },
最后,數據格式:以下是模擬數據
let city = [
{ name: '北京', enName: 'bj', children: [ { name: '朝陽區', enName: 'cyq' }, { name: '大興區', enName: 'dxq' }, { name: '昌平區', enName: 'cpq' } ] }, { name: '天津', enName: 'tj', children: [ { name: '南開區', enName: 'nkq' }, { name: '和平區', enName: 'hpq' }, { name: '西青區', enName: 'xqq' } ] } ] this.cdList = city
看結果:
獲取焦點之后,顯示所有的數據
中文搜索:
英文搜索:
這就實現了,輸入子節點或者父節點的名稱顯示相應的父節點或子節點。
以下是完整代碼:
<template>
<el-popover placement="bottom-start" trigger="click" style="width:100%;" v-model="cdListVisible">
<el-tree :data="cdList" :props="{ label: 'name', children: 'children' }"
node-key="id" ref="cdListTree" :filter-node-method="filterNodeTree" @current-change="currentHandle"> </el-tree> <template> <el-input slot="reference" v-model="dataForm.parentName" @input="filterInput" placeholder="設備樹"></el-input> </template> </el-popover> </template> <script> export default { data () { return { visible: false, cdList: [], // 城市菜單列表 cdListVisible: false, dataForm: { parentName: '' } } }, methods: {
filterChange () {
//調用el-tree的filter方法,觸發條件過濾,並將當前輸入的信息傳遞到事件內部
this.$refs.cdListTree.filter(this.dataForm.parentName) }, // 調用tree過濾方法 中文英過濾 filterNode (value, data, node) { if (!value) { node.expanded = false return true } // 查詢列表是否有匹配數據 let val = value.toLowerCase() return this.chooseNode(val, data, node) }, // 過濾父節點 子節點:如果輸入的參數是父節點且能匹配,則返回該節點以及其下的所有子節點;如果參數是子節點,則返回該節點的父節點。 chooseNode (value, data, node) { if (data.name.indexOf(value) !== -1 || data.enName.indexOf(value) !== -1) { return true } const level = node.level // 如果傳入的節點本身就是一級節點就不用校驗了 if (level === 1) { return false } // 先取當前節點的父節點 let parentData = node.parent // 遍歷當前節點的父節點 let index = 0 while (index < level - 1) { // 如果匹配到直接返回 匹配中英文過濾,name中文,enName英文 if (parentData.data.name.indexOf(value) !== -1 || parentData.data.enName.indexOf(value) !== -1) { return true } // 否則的話再往上一層做匹配 parentData = parentData.parent index++ } // 沒匹配到返回false return false },
// 點擊選中 currentHandle (selectData) { if (selectData.children.length === 0) { this.dataForm.parentName = selectData.name this.cdListVisible = false } } } </script>
至此,搜索過濾完畢,有不正之處還望指出,謝謝呀呀~~