Реализовать возможность настройки таблицы на основе element-ui

Element Vue.js

написать впереди

Благодарим фронтенд-команду Ele.me за предоставление компонентного фреймворка.elememt-ui, основные компоненты этой статьи используют element-ui.

большой фон

В процессе разработки некоторых систем неизбежно использование таблицы для отображения данных. Давайте сначала взглянем на компонент el-table.

Очень простой и удобный в использовании компонент, который настраивает данные и метку каждого столбца таблицы в соответствии с предоставленными данными. Да, это вроде бы нормально, но при разработке большого количества страниц, содержащих таблицы, вы обнаружите, что вам нужно каждый раз копировать el-table-column, или вы скажете, что уже атрибутировали документ всего набора фреймворка element-ui. Однако существует много повторяющегося кода и большой объем кода. Как программисту, однажды вам нужно написать определенный фрагмент кода, который вы уже написали, не чувствуете ли вы себя немного неуместным? . .

управляемый данными

<el-table
  :data="tabledata">
   <el-table-column
    v-for="(item,key) in columnsConfig"
    :key="key"
    :label="item.label"
    :prop="item.prop">
    </el-table-column>
</el-table>
data () {
  return {
    columnsConfig: [{
      prop: 'logicCategoryId',
      label: '编号(ID)'
    }, {
      prop: 'name',
      label: '分类名称'
    }]
  }
}

Это упрощает визуализацию таблицы.

Вот небольшая хитрость

el-table-column под преобразованием

<el-table
  :data="tabledata">
   <el-table-column
    v-for="(item,key) in columnsConfig"
    :key="key"
    v-bind="item">// 这里改造
    </el-table-column>
</el-table>

v-bind может привязать объект, который будет считывать каждое свойство объекта элемента и использовать его в компоненте. Например, чтобы увеличить ширину: 100, вам нужно только добавить ширину ни к одному элементу в columnsConfig, и el-table-column не нужно изменять.

Как использовать слоты

<el-table-column
  label="日期"
  width="120">
  <template scope="scope">{{ scope.row.date }}</template>
</el-table-column>

Очевидно, что конфигурация слотов el-table-column не может использоваться в массиве columnsConfig. Найдите решение в исходном коде (путь к файлу: node_modules_element-ui@1.3.7@element-ui\packages\table\src\table-column.js), код функции создания хука выглядит следующим образом:

Визуализируйте каждую ячейку таблицы в функции this.columnConfig.renderCell.Если используются слоты, содержимое слотов будет прочитано. Напишите новый компонент, используя vue extends, унаследуйте el-table-columns и перепишите функцию renderCell, чтобы изменить ее возвращаемое содержимое.В это время используйте jsx для возврата содержимого с функцией return slots.

Во-первых, посмотрите, как написан columnsConfig

columnsConfig: [{
  cellType: 'slots',// 不是所有的列都需要重写,加个字段标记下
  prop: 'logicCategoryId',
  label: '编号(ID)',
  renderCell: (scope) => {
    return (
      <el-button type="text" on-click={() => that.viewGoods(scope.row)}>
        { scope.row.productCount }
      </el-button>
    )
  }
}, {
  prop: 'name',
  label: '分类名称'
}],

Во-вторых, разработайте новый компонент column-plus.vue, код выглядит следующим образом.

<script>
import { TableColumn } from 'element-ui'
// renderCell 函数,类型可扩展
const renderCell = {
  slots: function (h, data) {
    // 接受传入的renderCell函数
    let renderCell = () => {
      return this.renderCell ? this.renderCell(data) : ''
    }
    return <div class="cell">{ renderCell(h, data) }</div>
  }
}
export default {
  extends: TableColumn,// 继承el-table-column
  props: {
    prop: {
      type: [String, Number]
    },
    cellType: {
      type: String,
      validator: function (value) {
        let valid = ['text', 'input', 'slots'].includes(value)
        !valid && console.error(`columnPlus组件不适配 ${value} 类型`)
        return valid
      }
    },
    renderCell: {
      type: Function
    }
  },
  // el-table-column 先调用在调用本身的
  created () {
    if (renderCell[this.cellType]) {
      this.columnConfig.renderCell = renderCell[this.cellType].bind(this)
    }
  }
}
</script>

Наконец, компонент использует шаблон для настройки данных.

<el-table
  :data="tabledata">
   <column-plus v-bind="item" v-for="(item,key) in columnConfigs" :key="key">
  </column-plus>
</el-table>

Данные конфигурации

columnsConfig: [{
  cellType: 'slots',
  prop: 'logicCategoryId',
  label: '编号(ID)',
  renderCell: (scope) => {
    return (
      <el-button type="text" on-click={() => that.viewGoods(scope.row)}>
        { scope.row.productCount }
      </el-button>
    )
  }
}, {
  prop: 'name',
  label: '分类名称'
}]****

написать на обороте

Разработка компонентов реализует настраиваемую разработку, которая позволяет достичь цели быстрой разработки и упростить код. Необходимо объяснить свойства vue extends и mixins, эти два свойства являются наследованием, свойства и методы переопределены, функция ловушки состоит в том, чтобы сначала вызвать родительский класс, чтобы вызвать себя, приведенный выше пример (el-table-column сначала вызывает себя), но разница в следующем:

  • расширяет одиночное наследование, используя при этом высокий приоритет
  • Множественное наследование Mixins с низким приоритетом

Кроме того, vue-cli использует jsx для написания трех подключаемых модулей, которые необходимо установить.

  • babel-helper-vue-jsx-merge-props
  • babel-plugin-syntax-jsx
  • babel-plugin-transform-vue-jsx

Пополнить

Я не ожидал, что такой маленький партнер прочитает это после того, как я разместил его в течение дня.Есть несколько моментов, которые нужно добавить.

Комментарии в области комментариев @hold такие же, как у iview. Позже я пошел посмотреть документацию iview. Я никогда не использовал iview для его разработки. Я не знаю, что таблица также реализована с рендером. После обмена это, я узнал больше Спасибо @hold.

Этоiview, код табличного компонента

render: (h, params) => {
    return h('div', [
        h('Button', {
            props: {
                type: 'text',
                size: 'small'
            }
        }, 'View'),
        h('Button', {
            props: {
                type: 'text',
                size: 'small'
            }
        }, 'Edit')
    ]);
}

Конечно, после использования рендера вам нужно использовать фильтр, что более неудобно. Однако фильтр vue на самом деле является синтаксическим сахаром, и окончательная компиляция компилируется в обработку функций.

Так что, если вы хотите использовать фильтр?

data () {
    return {
      columns: [{
        renderCell: (scope) => {
          return (
              { that.stateTxt(scope.row.state)}
          )
        }
      }]
    }
    },
    methods: {
        stateTxt (val) {}
    }

Любой, кто написал React, знает, как это сделать.

Поэтому всегда была тема для споров писать js на html или html на js во фронтенде, как выбрать и разработать самому.

Код без рендера такой

<template>
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        prop="date"
        label="日期"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="地址">
      </el-table-column>
    </el-table>
  </template>

Обработка с помощью рендера выглядит так

<el-table
  :data="tabledata">
   <column-plus v-bind="item" v-for="(item,key) in columnConfigs" :key="key">
  </column-plus>
</el-table>

data () {
    return {
      columnConfigs: [{
        label: '日期',
        width: '180',
        prop: 'date'
      }, {
        label: '姓名',
        width: '180',
        prop: 'name'
      }, {
        label: '地址',
        prop: 'address'
      }]
    }
}