shizhihuaxu / study-notes

学习笔记,见 issues
0 stars 0 forks source link

view-ui 脱坑实录 #6

Open shizhihuaxu opened 4 years ago

shizhihuaxu commented 4 years ago
  1. 重置表单单个字段,清空校验提示

    this.$refs.myForm.fields.forEach((e) => {
       if (e.prop === 'abcd') {
           e.resetField()
       }
    })
shizhihuaxu commented 4 years ago
  1. 循环生成 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`)
shizhihuaxu commented 4 years ago
  1. 重置 Table 组件表头筛选条件为空
// 表格组件
<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)
                }
            })
        }
    }
}
shizhihuaxu commented 4 years ago
  1. 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)
           },
       }
    }
shizhihuaxu commented 3 years ago

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 属性,此属性可以设置列筛选的默认选中项;

shizhihuaxu commented 2 years ago
  1. 循环动态生成的表单,删除某个列表项后立即校验报错 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>