前端

vue中动态组件的动态创建

2021-01-12  本文已影响0人  若年
 this.$options.components['publicassetTable'] = datatableCreater({
        name: 'publicassetTable',
        storeGetter: ['assetpool/_gbox_assetDetailListGridRows'],
        storeLoads: [],
        maxHeight: 500,
        showIndex: false,
        showCheckBox: true,
        showExpand: false, // 主表格
        fixed: true,
        columns: column
      })
      this.creatTableLables = 'publicassetTable'
      column = []
  <component
          ref="assetDetailTable"
          v-bind:is="creatTableLables"
          @selection-change="changeDetailSelection"
          @row-click="onDetailRowClick"
        >
</component>

datatableCreater.js

// "date": "2016-05-03",
//             "name": "王小虎",
//             "address": "上海市普陀区金沙江路 1518 弄",
//             "group": 1,
//             "group_desc": "普陀区"
// columnsFilter:[{[field&field1]: 'date | text | select'}],
// columnsSort: [{[field]: sortFn|default}],
// columns: [{property, width, label, children: [分组header]}],
// renderColumn: function(),
// renderRow: function(),
// actionHander: function(),
// actions: [{[text]: 'action'}]
// 列格式化
// <template v-slot:date="scope">
//    {{scope.row.date}}/{{scope.row.name}}
// </template>
// 表格业务组件动态创建
export default function (bzConifg) {
  return {
    name: bzConifg.name,
    inheritAttrs: false,
    created () {
      this.loadData()
    },
    data () {
      return {}
    },
    props: {
      maxHeight: {
        type: Number,
        default: bzConifg.maxHeight
      },
      height: {
        type: Number,
        default: bzConifg.height
      },
      actions: {
        type: Object | Boolean,
        default: () => bzConifg.actions
      },
      params: {
        type: Object,
        default: () => ({})
      },
      data: {
        type: Array,
        default: () => []
      }
    },
    watch: {
      params () {
        this.loadData()
      }
    },
    computed: {
      _datasFn () {
        const staticdata = this.data
        if (bzConifg.storeGetter && bzConifg.storeGetter[0]) {
          if (bzConifg.transFormData && bzConifg.transFormData instanceof Function) {
            return bzConifg.transFormData(this.$store.getters[bzConifg.storeGetter[0]], this)
          }
          return this.$store.getters[bzConifg.storeGetter[0]]
        }
        return staticdata
      },
      _datas () {
        const d = this._datasFn
        return typeof d === 'function' ? d(this.params) : d
      },
      _tableProps () {
        return {
          data: this._datas,
          height: this.height,
          maxHeight: this.maxHeight,
          'highlight-current-row': true,
          size: 'mini',
          'row-class-name': bzConifg.rowClassName,
          border: (bzConifg.border !== false),
          'show-header': (bzConifg.showHeader !== false)
        }
      }
    },
    methods: {
      loadData () {
        if (bzConifg.storeLoads && bzConifg.storeLoads.length > 0) {
          const params = this.params || {};
          const attrs = this.$attrs || {};
          this.$store.dispatch(bzConifg.storeLoads[0], {
            ...params,
            ...attrs
          })
          return
        }
      },
      actionHander (v, scope) {
        this.$emit('actionHandler', {
          action: v,
          payload: scope
        })
      },
      renderCellSlot (slotName, props) {
        return this.$scopedSlots[slotName](props)
      },

      sortColums (clos) {
        return clos
      },
      // 获取表格 某个 key 组成的数组
      getDataByKey (key) {
        if (key) {
          return _.uniq(this._datas.map(item => item[key]) || [])
        }
      },
      // 获取表格所有数据
      getAllData () {
        return this._datas
      },
      createElColumn (c, index, createElement) {
        return {
          props: {
            prop: c.prop,
            label: c.label,
            fixed: (index === 0 && bzConifg.fixed === true) || (c.prop === '__&action&__' && 'right'),
            width: c.width,
            sortable: c.sortable,
            'min-width': c['min-width'],
            type: c.type,
            align: c.align,
            'header-align': c['header-align'] || c.headerAlign,
            showOverflowTooltip: (c.showOverflowTooltip !== false)
          },
          scopedSlots: {
            default: ((this.$scopedSlots[c.slot] && {
              default: props => {
                return this.renderCellSlot(c.slot, props)
              }
            }) || (c.prop === '__&action&__' && {
              default: props => {
                if (this.$scopedSlots.actions) {
                  return this.$scopedSlots.actions(props)
                }
                // 创建action列 el-menu
                const keys = Object.keys(this.actions.buttons);
                const limits = keys.length < 4 ? keys : keys.filter((r, index) => index < 2)
                const limitButons = limits.map(text => createElement(
                  'span',
                  {
                    style: {
                      'display': 'inline-block',
                      'margin-left': '10px',
                      'font-size': '14px',
                      'color': '#234dbb',
                      'text-decoration': 'underline',
                      'cursor': 'pointer'
                    },
                    on: {
                      click: this.actionHander.bind(this, this.actions.buttons[text], props)
                    }
                  },
                  text
                ))
                const moreElMenuItems = keys.filter((r, index) => keys.length > 3 && index > 1).map((text, index) => createElement('el-dropdown-item', {}, text))
                const subMenus = createElement('el-dropdown-menu', { slot: 'dropdown' }, [...moreElMenuItems])
                const moreTitle = createElement('span', {
                  style: {
                    'display': 'inline-block',
                    'margin-left': '10px',
                    'font-size': '14px',
                    'color': '#234dbb',
                    'text-decoration': 'underline',
                    'cursor': 'pointer'
                  }
                }, ['更多', createElement('i', { 'class': { 'el-icon-arrow-down': true, 'el-icon--right': true } })])
                return [...limitButons, moreElMenuItems.length > 0 && createElement('el-dropdown', { props: { size: 'mini' } }, [moreTitle, subMenus])]
              }
            }) || {}).default,
            header: (c.headerSlot && this.$scopedSlots[c.headerSlot] && {
              header: column => {
                return this.$scopedSlots[c.headerSlot](column)
              }
            } || {}).header

          }
        }
      },
      // 分组处理
      groupCreateElColumn (createElement, colum, index) {
        if (!colum.childrens) {
          return createElement('el-table-column', this.createElColumn(colum, index, createElement))
        }
        const chilidColumS = (colum.childrens || []).map(col => {
          return this.groupCreateElColumn(createElement, col, index)
        });
        return createElement('el-table-column', {
          props: {
            label: colum.label,
            align: colum.align
          }
        }, chilidColumS)
      }
    },
    render (createElement, contenxt) {
      // 创建行号
      let indexItme = { type: 'index', fixed: bzConifg.fixed, width:bzConifg.indexWidth || 50, prop: '__$index$__', label: '编号' }
      if(bzConifg.indexWidth === 'auto'){
        delete indexItme.width
      }
      const indexColums = bzConifg.showIndex ? [indexItme] : []
      // 创建checkbox
      const checkboxColums = bzConifg.showCheckBox ? [{ type: 'selection', fixed: bzConifg.fixed, width: 50, prop: '__$selection$__' }] : []

      //  创建expand
      const expandColums = bzConifg.showExpand ? [{ type: 'expand', slot: bzConifg.showExpand || 'expandslot', fixed: bzConifg.fixed, width: 50, prop: '__$expand$__', label: '' }] : []

      // 创建actions
      const actonColum = this.actions ? [{
        label: this.actions.label,
        width: this.actions.width,
        align: this.actions.align,
        prop: '__&action&__'
      }] : []
      // 创建columns
      const ElColumns = this.sortColums([...indexColums, ...checkboxColums, ...expandColums, ...bzConifg.columns, ...actonColum]).map((c, index) => {
        return this.groupCreateElColumn(
          createElement,
          c,
          index
        )
      })
      // 创建表格
      const _tableProps = {
        'class': {},
        ref: 'eltable',
        style: {
          width: '100%'
        },
        props: {
          ...this._tableProps
        },
        on: this.$listeners
      }
      return createElement('el-table', _tableProps, ElColumns)
    }
  }
}

上一篇下一篇

猜你喜欢

热点阅读