Skip to content
Last updated: 2019-01-31
<

TIP

Vue 2

iView “多列指标筛选的表格”

展示效果及示例代码
此处原样引用,作为对比

vue
<template>
  <Checkbox-group v-model="tableColumnsChecked" @on-change="changeTableColumns">
    <Checkbox label="show">Show</Checkbox>
    <Checkbox label="weak">Weak</Checkbox>
    <Checkbox label="signin">Signin</Checkbox>
    <Checkbox label="click">Click</Checkbox>
    <Checkbox label="active">Active</Checkbox>
    <Checkbox label="day7">7, retained</Checkbox>
    <Checkbox label="day30">30, retained</Checkbox>
    <Checkbox label="tomorrow">The next day left</Checkbox>
    <Checkbox label="day">Day Active</Checkbox>
    <Checkbox label="week">Week Active</Checkbox>
    <Checkbox label="month">Month Active</Checkbox>
  </Checkbox-group>
  <Table :data="tableData2" :columns="tableColumns2" border></Table>
</template>
<script>
  export default {
    data() {
      return {
        tableData2: this.mockTableData2(),
        tableColumns2: [],
        tableColumnsChecked: ['show', 'weak', 'signin', 'click', 'active', 'day7', 'day30', 'tomorrow', 'day', 'week', 'month']
      }
    },
    methods: {
      mockTableData2() {
        let data = [];

        function getNum() {
          return Math.floor(Math.random() * 10000 + 1);
        }
        for (let i = 0; i < 10; i++) {
          data.push({
            name: 'Name ' + (i + 1),
            fav: 0,
            show: getNum(),
            weak: getNum(),
            signin: getNum(),
            click: getNum(),
            active: getNum(),
            day7: getNum(),
            day30: getNum(),
            tomorrow: getNum(),
            day: getNum(),
            week: getNum(),
            month: getNum()
          })
        }
        return data;
      },
      getTable2Columns() {
        const table2ColumnList = {
          name: {
            title: 'Name',
            key: 'name',
            fixed: 'left',
            width: 200,
            render: (h, params) => {
              const fav = this.tableData2[params.index].fav;
              const style = fav === 0 ? {
                cursor: 'pointer'
              } : {
                cursor: 'pointer',
                color: '#f50'
              };

              return h('div', [
                h('Icon', {
                  style: style,
                  props: {
                    type: fav === 0 ? 'ios-star-outline' : 'ios-star'
                  },
                  nativeOn: {
                    click: () => {
                      this.toggleFav(params.index);
                    }
                  }
                }),
                h('span', ' ' + params.row.name)
              ]);
            }
          },
          show: {
            title: 'Show',
            key: 'show',
            width: 150,
            sortable: true
          },
          weak: {
            title: 'Weak',
            key: 'weak',
            width: 150,
            sortable: true
          },
          signin: {
            title: 'Signin',
            key: 'signin',
            width: 150,
            sortable: true
          },
          click: {
            title: 'Click',
            key: 'click',
            width: 150,
            sortable: true
          },
          active: {
            title: 'Active',
            key: 'active',
            width: 150,
            sortable: true
          },
          day7: {
            title: '7, retained',
            key: 'day7',
            width: 150,
            sortable: true
          },
          day30: {
            title: '30, retained',
            key: 'day30',
            width: 150,
            sortable: true
          },
          tomorrow: {
            title: 'The next day left',
            key: 'tomorrow',
            width: 150,
            sortable: true
          },
          day: {
            title: 'Day Active',
            key: 'day',
            width: 150,
            sortable: true
          },
          week: {
            title: 'Week Active',
            key: 'week',
            width: 150,
            sortable: true
          },
          month: {
            title: 'Month Active',
            key: 'month',
            width: 150,
            sortable: true
          }
        };

        let data = [table2ColumnList.name];

        this.tableColumnsChecked.forEach(col => data.push(table2ColumnList[col]));

        return data;
      },
      changeTableColumns() {
        this.tableColumns2 = this.getTable2Columns();
      },
      toggleFav(index) {
        this.tableData2[index].fav = this.tableData2[index].fav === 0 ? 1 : 0;
      }
    },
    mounted() {
      this.changeTableColumns();
    }
  }
</script>

以上虽然能起到预期的演示作用,但代码略显冗繁,定义重复。
其实可好好利用 vuecomputed,既减少重复的数据结构定义,又能自动实现数据的响应,且不必监听 change 事件。
稍作优化如下:

vue
<template>
  <Checkbox-group v-model="tableColumnsChecked">
    <Checkbox v-for="c in tableColumns2" :label="c.key" :key="c.key">{{ c.title }}</Checkbox> <!--此处由数据自动遍历即可,不必一个个写出来-->
  </Checkbox-group>
  <Table :data="tableData2" :columns="selTableColumns2" border></Table>
</template>
<script>
  export default {
    data() {
      return {
        tableData2: this.mockTableData2(),
        //分拆tableColumns2,提出“固定列”部分,方便控制
        fixColumn: {
          title: 'Name',
          key: 'name',
          fixed: 'left',
          width: 200,
          render: (h, params) => {
            const fav = this.tableData2[params.index].fav;
            const style = fav ? {
              cursor: 'pointer'
            } : {
              cursor: 'pointer',
              color: '#f50'
            };

            return h('div', [
              h('Icon', {
                style: style,
                props: {
                  type: fav ? 'ios-star-outline' : 'ios-star'
                },
                nativeOn: {
                  click: () => {
                    this.toggleFav(params.index);
                  }
                }
              }),
              h('span', ' ' + params.row.name)
            ]);
          }
        },
        //除固定列外,其他列的数据,默认全部选中
        tableColumns2: [
          {
            title: 'Show',
            key: 'show',
            width: 150,
            sortable: true
          },
          {
            title: 'Weak',
            key: 'weak',
            width: 150,
            sortable: true
          },
          {
            title: 'Signin',
            key: 'signin',
            width: 150,
            sortable: true
          },
          {
            title: 'Click',
            key: 'click',
            width: 150,
            sortable: true
          },
          {
            title: 'Active',
            key: 'active',
            width: 150,
            sortable: true
          },
          {
            title: '7, retained',
            key: 'day7',
            width: 150,
            sortable: true
          },
          {
            title: '30, retained',
            key: 'day30',
            width: 150,
            sortable: true
          },
          {
            title: 'The next day left',
            key: 'tomorrow',
            width: 150,
            sortable: true
          },
          {
            title: 'Day Active',
            key: 'day',
            width: 150,
            sortable: true
          },
          {
            title: 'Week Active',
            key: 'week',
            width: 150,
            sortable: true
          },
          {
            title: 'Month Active',
            key: 'month',
            width: 150,
            sortable: true
          }
        ],
        //选中的列的key
        tableColumnsChecked: []
      }
    },
    methods: {
      //模拟表体数据
      mockTableData2() {
        let data = [];

        function getNum() {
          return Math.floor(Math.random() * 10000 + 1);
        }
        for (let i = 0; i < 10; i++) {
          data.push({
            name: 'Name ' + (i + 1),
            fav: false,//改数值为布尔值,控制更方便
            show: getNum(),
            weak: getNum(),
            signin: getNum(),
            click: getNum(),
            active: getNum(),
            day7: getNum(),
            day30: getNum(),
            tomorrow: getNum(),
            day: getNum(),
            week: getNum(),
            month: getNum()
          })
        }
        return data;
      },
      toggleFav(index) {
        this.tableData2[index].fav = !this.tableData2[index].fav;
      }
    },
    mounted() {
      //默认选中所有列
      this.tableColumnsChecked = this.tableColumns2.map(item => item.title)
    },
    computed: {
      //根据tableColumnsChecked筛选‘已选中’的列
      selTableColumns2() {
        return this.tableColumns2
                    .filter(col => this.tableColumnsChecked.includes(col.key))
                    .unshift(this.fixColumn) //在前面加入固定列
      }
    },
  }
</script>

Released under the MIT License.