熟悉vue项目的朋友都知道,有时候控件多的时候,在页面显示中会有排列的问题,甚至有些控件不需要,所以不需要的控件就可以不显示,这就涉及到动态添加控件的实现。
想要实现如下的功能:
其中代码片段为:
HTML
<div class="left-header">{{ $t('steamship.filter') }}</div>
<el-select
ref="selectRef"
v-model="selectProp.filter"
multiple
collapse-tags
value-key="name"
:placeholder="$t('steamship.pleaseSelect')"
:disabled="ifSelectDisabled"
@visible-change="e => visibleChange(e,selectProp.filter)"
@remove-tag="removeTag"
>
<el-option
v-for="item in filterOptions"
:key="item.name"
:label="item.label"
:value="item"
/>
</el-select>
<div style="margin-top: 5px">
<el-form
ref="filter"
:model="formProp.append"
label-width="120px"
label-position="left"
>
<el-form-item
v-for="item in filterList"
:key="item.prop"
:label="$t('steamship.' + item.name) + ':'"
>
<template v-if="item.type === 'remote'">
//这个组件时el-select远程搜索组件,自行封装的
<remote-select v-model="queryConditions[item.filterParam]"
:filed-name="item.filedName"
@change="handlerChangeFilter(item.filterParam)"
/>
</template>
<template v-else-if="item.type === 'select'">
<el-select
v-model="queryConditions[item.filterParam]"
multiple
collapse-tags
@change="handlerChangeFilter(item.filterParam)"
>
<el-option
v-for="sonItem in item.selectList"
:key="sonItem.code"
:label="sonItem.name"
:value="sonItem.code"
/>
</el-select>
</template>
<template v-else-if="item.type === 'slider'">
<div class="div-border-wrapper">
<el-slider
v-model="queryConditions[item.filterParam]"
range
:max="30"
@change="handlerChangeFilter(item.filterParam)"
/>
</div>
</template>
<template v-else-if="item.type === 'radio'">
<div class="div-border-wrapper">
<el-checkbox-group
v-model="queryConditions[item.filterParam]"
class="checkbox-style"
@change="handlerChangeFilter(item.filterParam)"
>
<el-checkbox label="1">{{ item.label1 }}</el-checkbox>
<el-checkbox label="0">{{ item.label2 }}</el-checkbox>
</el-checkbox-group>
</div>
</template>
</el-form-item>
</el-form>
</div>
js代码,data部分:
data(){
return {
filterList: [],
queryConditions: {
age: 30,
status: [],
operator: [],
owner: [],
eco: [],
scrubber: [],
operatorType: []
},
finallyParams: {},
}
}
js代码初始化动态控件列表,不全动态控件列表数据:
created() {
//在这里使用可枚举方法获取数据字典映射关系
this.getEnums()
},
methods:{
getEnums() {
//这里el-select的下拉列表由于是有数据字典映射关系的,所以先拿到el-select下拉列表数据,
//为了不必要的接口反复请求,数据字典统一存放在store中,其实
this.filterOptions.forEach(item => {
if (item.type === 'select') {
item.selectList = this.enums.vesselServiceStatusEnum
}
})
}
}
选中或者取消控件js代码:
// filter增加或者减少选中项时 重新设置绑定值
setParams(arr) {
arr.forEach(item => {
this.queryConditions[item.filterParam] = item.filterParam === 'age' ? 30 : []
this.finallyParams[item.filterParam] = undefined
})
},
// filter下拉框控件隐藏后触发,生成选择的控件
visibleChange(arg, val) {
if (!arg) {
// 拿到上一次选中的项的数组和当前选中的项的数组对比,取出不同的项
const differentArr = this.filterList.concat(val).filter((item, index, arr) => arr.indexOf(item) === arr.lastIndexOf(item))
if (differentArr.length) {
this.setParams(differentArr)
this.filterList = val
this.getList() //这个方法是设置控件参数后调用后台接口的方法
}
}
},
// filter下拉多选控件,多选模式下移除tag时触发
removeTag(val) {
this.setParams([val])
const index = this.filterList.findIndex(item => item.filterParam === val.filterParam)
this.filterList.splice(index, 1)
this.getList() //这个方法是设置控件参数后调用后台接口的方法
},
// filter选中生的控件 change事件
handlerChangeFilter(key) {
if (key === 'age') {
this.finallyParams[key] = this.queryConditions[key].join('-')
} else if (key === 'operator' || key === 'owner') {
this.finallyParams[key] = this.queryConditions[key].map(item => item.mapCode)
} else {
this.finallyParams[key] = this.queryConditions[key]
}
this.getList() //这个方法是设置控件参数后调用后台接口的方法
}
说明:
Filter控件中的下拉列表filterList会同选中的控件项对比元素,取出不同项,每一次的不同项绑定的参数进行置空还原,因为下一次再选中时绑定的值就是出事绑定值的状态,防止下一回选中时绑定值有默认的情况