关于ElementUi级联菜单远程搜索的问题

3,488 阅读2分钟

问题的来源

在最新的element-ui中,级联菜单的多选是搜索当前现有的数据,不能搜索远程的数据。当有很多数据时不能让后端把所有的数据都拿过来,这样请求就会变慢,这个时候element-ui的级联菜单就满足不了我们了,怎么办呢?

解剖

首先我们先去看Element-Ui给出的例子。我们看到他的dom节点里面有一个input,还有一个Popover弹出框组合而成的,我们知道官网给出了一个级联菜单面板,这样就解剖一下,就简单多了。


代码

让我们来看看怎么写吧。。。。

首先我们需要最外层写一个弹出框,并且这个弹框框是受控制的。

<el-popover      
 v-model="panelSelectShow"      
 ref="popover"      
 placement="bottom-start"      
 target="focus"    >
</el-popover>

然后我们填充一下我们的代码。又想input是能输入的,并且获取焦点的时候要显示级联菜单面板,失去焦点的时候要把面板删除掉,输入值的时候要能远程搜索。

<el-popover      
    v-model="panelSelectShow"      
    ref="popover"      
    placement="bottom-start"      
    target="focus"    >      
        <el-cascader-panel        
            v-loading="loading"        
            :options="cascaderCustomerData"        
            @change="handleChange"        
            :props="{children:'children',label:'name',value:'id'}"      
        ></el-cascader-panel>      
        <div class="el-cascader" slot="reference">        
            <el-input          
                size="mini"          
                filterable          
                clearable          
                autocomplete="off"          
                v-model="inputModel"          
                @input="handInput"          
                @blur="handleBlur"          
                @focus="handleFocus"
                @clear='handClear'
                placeholder="级联菜单"        >        
            </el-input>      
        </div>    
</el-popover>

接着,就有了下面的方法。。。。

data() {    
    return {      
        inputModel: "", //输入框中显示的值      
        panelSelectShow: false, // 是否显示级联菜单面板      
        loading: false,//给一个加载的loading      
        cascaderData: [], //       
        cascaderCustomerData: [], //控制面板显示的值      
        cascaderCustomerDataOld: [] // 当输入框的值为空时,把值存起来 避免多次请求    
    };  
},

// input输入    
handInput(val) {      
    if (!this.panelSelectShow) {        
        this.panelSelectShow = true;      
    }      
    if (!val) {        
        this.cascaderCustomerData = this.cascaderCustomerDataOld;        
        return;      
    }      
    this.getCutomerData(val).then(data => { 
        this.cascaderCustomerData = data;      
    });    
},

//清楚输入框    
handClear() {      
    this.inputModel = "";      
    this.cascaderData = [];      
    this.cascaderCustomerData = this.cascaderCustomerDataOld;      
    this.handleChange([]);    
},    
// 失去焦点    
handleBlur() {      
    let val = this.cascaderData || this.cascaderModel;      
    this.inputModel = val && val.length ? val[0] && val[1] ? val[0].split("|")[1] + " / " + val[1].split("|")[1] : val[0].split("|")[1] : "";    
},
// 获取焦点    
handleFocus() {      
    if (!(this.cascaderData && this.cascaderData.length)) {
        this.cascaderCustomerData = this.cascaderCustomerDataOld;
    }    
},
//请求后端接口
getCutomerData(name) {      
    this.loading = true;      
    let arr = new Promise((resolve, reject) => {        
        this.$axios.get(`/aa`).then(res => {
            let arr = [];
            res.data.data.map((el, i) => {
                arr[i] = {};                
                let departmentArr = [];
                el.department.map(e => { 
                    departmentArr.push({ id: e.id + "|" + e.department_name, department_name: e.department_name });
                    arr[i] = { id: el.id + "|" + el.company,  department_name: el.company, department: departmentArr };                
                });              
            });              
            if (!name) {
                this.cascaderCustomerDataOld = arr;              
            }              
            this.loading = false;
            resolve(arr);          
        }).catch(err => {            
            this.loading = false;
            resolve([]);
        });      
    });      
    return arr;    
}

当选择完成之后,获取一下我们选中的值。。

// 客户二级联动    
handleChange(val) {      
    this.panelSelectShow = false;      
    if (!(val && val.length)) {        
        this.cascaderCustomerData = this.cascaderCustomerDataOld;      
    }      
    this.inputModel = val && val.length  ? val[0] && val[1] ? val[0].split("|")[1] + " / " + val[1].split("|")[1] : val[0].split("|")[1] : "";      this.cascaderData = val;      let data = val && val.length ? val[0] && val[1] ? [val[0].split("|")[0], val[1].split("|")[0]] : [val[0].split("|")[0]] : [];      
// data 就是我们要的值
}

完结!

这是我写的第一篇文章,如有不足,请多多指教,哈哈.......