iView表格二次封装

2,046 阅读1分钟

在使用iview的过程中,很多时候需要处理大部分的表格,且操作是一样的时候,那么就可以抽出来,做成共公的一部分。方便偷懒~ 如图:

为了实现表格自带操作栏,且可以自定义覆盖,我们开始二次封装

原理

1.使用$attrs $listeners 全部传递iview Table组件默认的所有属性和事件
2.在自定义的组件中,修改columns的值,来实现我们想要的效果

实现

a.定义TableRender组件

<template>
  <Table v-bind="$attrs" v-on="$listeners"></Table>
</template>

<script type="text/jsx">
  import styles from './table-runder.module.less'
  export default {
    name: 'TableRender',
    props: {
      openAction: { // 是否开启操作列
        type: Boolean,
        default: true
      },
      action: { // 操作列附带的基础配置
        type: Object,
        default: () => {
          return {
            title: '操作',
            fixed: 'right',
            align: 'center',
            name: 'action'
          }
        }
      }
    },
    created () {
    },
    watch: {
      openAction: {
        handler (c) {
          c ? this.mergeColumns() : this.resetColumns()
        },
        immediate: true
      }
    },
    methods: {
      mergeColumns () {
        const { columns } = this.$attrs
        if (columns && columns[columns.length - 1].name === 'action') {
          return
        }
        const merge = this.getActions()
        columns.push(merge)
        this.$attrs.columns = columns
      },
      resetColumns () {
        const { columns } = this.$attrs
        if (columns && columns[columns.length - 1].name === 'action') {
          columns.pop()
          this.$attrs.columns = columns
        }
      },
      getActions () {
        const action = { ...this.action }
        let self = this
        return {
          ...action,
          render (h, params) {
            return (
              // 我也不晓得为啥 className={styles.tableBtn} 这样不生效,所以只能styles['table-btn'] :(
              <div class={styles['table-btn']}>
                <i-button type="success" size="small" nativeOnClick={self.viewHandle.bind(self, params)}>查看</i-button>
                <i-button nativeOnClick={self.editorHandle.bind(self, params)} type="primary"
                          size="small">编辑
                </i-button>
                <i-button nativeOnClick={self.removeHandle.bind(self, params)} type="error"
                          size="small">删除
                </i-button>
              </div>
            )
          }
        }
      },
      viewHandle (params) {
        this.$emit('on-view', params)
      },
      editorHandle (params) {
        this.$emit('on-editor', params)
      },
      removeHandle (params) {
        this.$emit('on-remove', params)
      }
    }
  }
</script>

<style scoped>

</style>

b.同级别的样式文件

ps: 因为在实现的过程中使用了jsx,所以要把css当成模块来引入。在vue中,默认是启用css modules了的,但要求是需要我们把要启用该特性的css文件以 .module.css文件结尾(预编译css一样)。

// table-runder.module.less
.table-btn {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-content: flex-start;
}

c.调用

<template>
  <div class="container">
    <h2>tableRender</h2>
    <TableRender :open-action="true" :columns="tableTitle" :data="testList" @on-view="viewHandle"></TableRender>
  </div>
</template>

<script type="text/jsx">
  import TableRender from '@/common/TableRender'

  export default {
    name: 'test',
    components: {
      TableRender
    },
    data () {
      return {
        testList: [
          { name: '张三', status: true },
          { name: '李四', status: true },
          { name: '王五', status: false },
          { name: '钱六', status: true }
        ],
        tableTitle: [
          {
            title: '序号',
            fixed: 'left',
            align: 'center',
            width: 65,
            type: 'index'
          }, {
            title: '名称',
            key: 'name'
          }, {
            title: '状态',
            align: 'center',
            minWidth: 120,
            key: 'status',
            render: (h, params) => {
              const { row: { status } } = params
              return (
                <p>{status ? '是' : '否'}</p>
              )
            }
          }
          // 指定列属性name为action,可启用自定义的操作,可以覆盖默认的操作栏的设置: 注: open-action 设置为false后失效
          // {
          //   title: 'Action',
          //   name: 'action',
          //   render: (h, params) => {
          //     return (
          //       <div>
          //         <i-button type="primary">View</i-button>
          //         <i-button type="primary">Del</i-button>
          //       </div>
          //     )
          //   }
          // }
        ]
      }
    },
    mounted () {
    },
    methods: {
      viewHandle (params) {
        this.$Modal.info({
          content: JSON.stringify(params, null, '\t ')
        })
      }
    }
  }
</script>

<style scoped>
  .container {
    padding: 20px;
  }
</style>

参数

属性 说明 类型 默认值
open-action 是否启用操作栏,关闭后table将不再支持操作栏 Boolean true
action 操作栏的属性 Object {title: '操作', fixed: 'right', align:'center', name: 'action', render: Function}

自定义的列参见调用列中注释的代码

github代码