vue element table 封装

2018-06-30  本文已影响0人  听下雨的声音yh
<script>
  // 表格REF
  const TABLE_REF = `my-table-${parseInt(Math.random())}`
  export default {
    name: 'MyTable',
    // 组件
    components: {},
    props: {
      // 表格数据
      data: Array,
      // 每列显示内容
      columns: Array,
      // el-table属性
      tableProps: Object,
      // 选中行
      selection: Array
    },
    // 组件渲染函数
    render (h) {
      const generateTableColumn = (col, index) => {
        if (col.children) {
          // 如果当前列有children列
          const eTableColumn = h(
              'el-table-column',
              {
                props: this.showColumnProps(col),
                key: `${col.prop}-${index}`
              },
              col.children.map((child, index2) => {
                return generateTableColumn(child, `${index}-${index2}`)
              })
          )
          return eTableColumn
        } else if (this.$scopedSlots[col.prop]) {
          // 如果当前列有对应的scope-slot
          const eTableColumn = h(
              'el-table-column',
              {
                props: this.showColumnProps(col),
                scopedSlots: {
                  default: this.$scopedSlots[col.prop]
                },
                key: `${col.prop}-${index}`
              }
          )
          return eTableColumn
        } else {
          const eTableColumn = h(
              'el-table-column',
              {
                props: this.showColumnProps(col),
                key: `${col.prop}-${index}`
              }
          )
          return eTableColumn
        }
      }
      // 还需要将全部事件绑定到el-table上
      // 处理v-bind传递的全部props
      const tableProps = Object.assign({data: this.data}, this.showTableProps)
      // 使用展开运算符绑定所有Prop到el-table中
      const eColumns = this.columns.map((column, index) => {
        return generateTableColumn(column, index)
      })
      const tableListeners = this.showListeners
      // 直接在columns中传多一个{type: 'selection', width: '55'}即可启用多选列
      const eTable = h(
          'el-table',
          {
            props: tableProps,
            on: tableListeners,
            ref: TABLE_REF,
            directives: [
              {
                name: 'loading',
                value: this.tableProps ? this.tableProps.loading : false
              }
            ]
          },
          eColumns
      )
      // 组件根节点
      const eRoot = h(
          'div',
          {
            'class': {
              'dn-table': true
            }
          },
          [eTable]
      )
      return eRoot
    },
    // 数据对象,本页面用到的所有数据
    data () {
      return {
        // el-table-column 的默认属性
        defaultColumnProps: {
          align: 'center',
          headerAlign: 'center'
        },
        // el-table 的默认属性
        defaultTableProps: {
          border: true,
          loading: false,
          'row-class-name': 'row',
          'element-loading-text': '拼命加载中'
        }
      }
    },

    // 计算属性
    computed: {
      // 每列
      columnsList () {
        return this.columns
      },
      // el-table 属性
      showTableProps () {
        return Object.assign({}, this.defaultTableProps, this.tableProps)
      },
      // el-table Events
      showListeners () {
        let defaultListeners = {}
        if (this.selection) {
          let fnc = selection => {
            this.$emit('update:selection', selection)
            if (this.$listeners['selection-change']) {
              this.$listeners['selection-change'](selection)
            }
          }
          defaultListeners['selection-change'] = fnc
        }
        return Object.assign({}, defaultListeners, this.$listeners)
      },
      toggleRowSelection () {
        return this.$refs[TABLE_REF].toggleRowSelection
      },
      elTable () {
        return this.$refs[TABLE_REF]
      }
    },

    // 监控
    watch: {},

    // 方法与事件处理
    methods: {
      // el-table-column 属性
      showColumnProps (prop) {
        let newProp = Object.assign({}, this.defaultColumnProps, prop)
        // 获取自定义表头的scopeSlot
        const headerSlot = this.$scopedSlots[`${prop.prop}#header`]
        // 将自定义表头的scopeSlot覆盖至renderHeader
        if (headerSlot) {
          newProp.renderHeader = headerSlot
        }
        // 删除无关属性
        delete newProp.children
        return newProp
      },
      // 选中事件
      handleSelectionChange (selection) {
        this.$emit('update:selection', selection)
      }
    },

    // 组件生命周期钩子,一般常用的是 mounted
    mounted () {
    }
  }
</script>


上一篇下一篇

猜你喜欢

热点阅读