Open shizhihuaxu opened 4 years ago
循环生成 FormItem ,如何将 prop 设置为对象的深层属性,如何校验单个字段
// data 的数据结构
myData: {
args: [
{
enabled: false, // boolean
ports: [{ name: '', ip: '' }, { name: 'LAN2', ip: '' }],
},
{
enabled: true, // boolean
ports: [{ name: '', ip: '' }, { name: '', ip: '' }],
},
],
},
// 循环生成表单
<Form
ref='myForm'
:model='myData'
>
// 使用 template 包裹避免产生冗余渲染标签
<template v-for='(item, index) in myData.args'>
<FormItem
v-if='item.enabled'
:prop='"args." + index + ".ports[0].ip"' // 如何绑定 prop
:rules='ipValidator[index]'
>
<Input
v-model='item.ports[0].ip' // prop 对象深层的属性
></Input>
</FormItem>
<FormItem
v-if='item.enabled'
:prop='"args." + index + ".ports[1].ip"' // 如何绑定 prop
:rules='ipValidator[index]'
>
<Input
v-model='item.ports[1].ip' // prop 对象深层的属性
></Input>
</FormItem>
</template>
</Form>
// 如何校验此情况下的单个 prop 字段 拼接
this.$refs.myForm.validateField(`args.${argsIndex}.ports[${portsIndex}].ip`)
// 表格组件
<Table :columns="tableColumns" ref='myTable'></Table>
export default {
computed: {
// 表格列
tableColumns () {
const columns = [
{
title: '测试筛选',
key: 'test',
filterMultiple: false,
filters: [{ // 筛选
label: '张三',
value: 1,
},{
label: '李四',
value: 2,
}],
},
]
return columns
}
},
methods: {
// 重置表头筛选默认值
reset() {
this.tableColumns.forEach((item, index) => {
if ('filters' in item) { // 存在筛选功能的列
this.$refs.myTable.handleFilterReset(index)
}
})
}
}
}
Table 单项选中与取消,全选与取消,清除选中状态
export default {
data() {
return {
checkedIds: new Set()
}
},
methods: {
// 重置选中项状态
getListAndReset(clearCheckedIds = true) {
this.$api.apiRequest().then(res => {
if (res && res.status === 200) {
const { results } = res.data
clearCheckedIds ? this.checkedIds.clear() : '' // 重置选中项
results.map(item => {
// 重置选中项状态
item._checked = this.checkedIds.has(item.id)
})
this.tableData = results
}
})
},
// 全选
handleSelectAll (selectedArr) {
selectedArr.map(item => {
this.checkedIds.add(item.id)
})
},
// 取消全选
handleSelectAllCancle (tableRef) {
const data = this.$refs[tableRef].data
data.forEach((item) => {
if (this.checkedIds.has(item.id)) {
this.checkedIds.delete(item.id)
}
})
},
// 选中某一项
handleSelect (selection, row) {
this.checkedIds.add(row.id)
},
// 取消选中某一项,为了兼顾全选后取消选中某一项,要从已选择的列表里删掉这一项,而不是直接使用已选中项
handleSelectCancle (selection, row) {
this.checkedIds.delete(row.id)
},
}
}
5、Table 联动筛选,动态设置某列可筛选项后,之前的列筛选选中状态丢失问题解决方案
<Table :columns='tableColumns' :data='[]'></Table>
data() {
return {
otherFiletrs: [], // 其他筛选
categotyFilters: [], // 类别筛选
typeFilters: [], // 类型筛选
// 向后端请求数据
filterParams: {
other: '',
categoty: '',
type: ''
}
}
},
computed() {
tableColumns() {
const columns = []
columns.push({
title: '其他',
key: 'other',
filterMultiple: false,
filters: this.otherFilters,
filterRemote: (arr) => {
this.filterParams.other = arr[0] !== undefined ? arr[0] : ''
this.searchEvents()
}, {
title: '类别',
slot: 'category',
filterMultiple: false,
filters: this.categoryFilters,
filterRemote: (arr, key, column) => {
const value = arr[0] !== undefined ? arr[0] : ''
let typeArr = []
this.filterParams.type = '' // 重置类型筛选条件
// 同步调整类型筛选条件,执行initTypeFilters 方法会导致表头重新渲染,之前项选中状态丢失
switch (value) {
case 1:
typeArr = [1, 2, 3, 4, 5, 30]
this.initTypeFilters(typeArr)
break
case 2:
typeArr = [6]
this.initTypeFilters(typeArr)
break
default:
this.typeFilters = []
break
}
this.filterParams.category = value
// 关键:保持之前选中的项的选中状态
this.filterParams.other ? this.tableColumns[1].filteredValue = [this.filterParams.other] : ''
this.filterParams.category ? this.tableColumns[3].filteredValue = [this.filterParams.category] : ''
this.searchEvents()
},
}, {
title: '类型',
key: 'type',
filterMultiple: false,
filters: this.typeFilters,
filterRemote: (arr) => {
this.filterParams.category = arr[0] !== undefined ? arr[0] : ''
this.searchEvents()
})
}
},
methods: {
// 根据传入的类别字段设置类型可选项
initTypeFilters (arr) {
this.typeFilters = []
Object.keys(typeStatic).forEach(key => {
key = Number(key)
if (arr.indexOf(key) !== -1) {
this.typeFilters.push({
label: typeStatic[key],
value: key,
})
}
})
},
}
关键代码:this.tableColumns[index].filteredValue = [value]
,Table 列表中某两个列的筛选为联动筛选,也就是设置完前一列的筛选项才需要出现后一列的筛选项,此时动态设置后一列的可筛选项会导致列表表头刷新重置,丢失此选项之前所有的列表筛选项选中状态,此时可以为 Table 组件的 column 项设置 filteredValue 属性,此属性可以设置列筛选的默认选中项;
循环动态生成的表单,删除某个列表项后立即校验报错 please transfer a valid prop path to form item!
,解决方案是删除后校验的操作写在 nextTick
中。
<template>
<Form
ref='myForm'
:model='configData'
>
<div
v-for='(configItem, index) in configData.config'
:key='index'
>
<FormItem
:prop='`config.${index}.regex`'
:rules='formValidators.regex'
>
<Input
v-model='configItem.regex'
></Input>
</FormItem>
<FormItem
:prop='`config.${index}.target_fields`'
:rules='formValidators.target_fields'
>
<Input
v-model.trim='configItem.target_fields'
></Input>
</FormItem>
<!-- 删除按钮 -->
<Button @click='delete(index)'></Button>
</div>
</Form>
</template>
<script>
export default {
data() {
return {
// 表单数据
configData: {
a: 1,
config: [
{
regex: '1',
target_fields: 2
}
]
},
// 表单校验
formValidators: {
regex: [{ required: true, message: '请输入' }],
target_fields: [{ required: true, message: '请输入' }],
}
}
},
methods: {
// 校验 保存
save() {
this.$refs.myForm.validate((valid) => {
if (valid) {
// ...
}
})
},
// 删除一项
delete(index) {
this.configData.config.splice(index, 1)
// 想在删除时立即调用一次保存接口,必须放在 nexttick 中,保证列表渲染更新
this.$nextTick(() => {
this.save()
})
}
}
}
</script>
重置表单单个字段,清空校验提示