njleonzhang / vue-data-tables

A simple, customizable and pageable table with SSR support, based on vue2 and element-ui
https://njleonzhang.github.io/vue-data-tables
MIT License
1.02k stars 221 forks source link

「彻底解放双手」的建议 #223

Open zaxlct opened 5 years ago

zaxlct commented 5 years ago

Please follow the issue template, or your issue may be closed automatically.

For bug report, provide the following section

Online reproduce

感谢作者的 vue-data-tablesel-form-dialog,我的管理后台项目中大量使用了它们,真心舒服~省了很多代码(先舔一波😂)

不过我觉得这些加起来还是没有彻底解放双手,有个痛点没解决: 平时我们使用的 element table 时候往往是这样写的

    <el-table-column
      label="日期"
      width="180">
      <template scope="scope">
        <el-icon name="time"></el-icon>
        <span style="margin-left: 10px">{{ scope.row.date }}</span>
      </template>
    </el-table-column>
    <el-table-column
      label="姓名"
      width="180">
      <template scope="scope">
        <el-popover trigger="hover" placement="top">
          <p>姓名: {{ scope.row.name }}</p>
          <p>住址: {{ scope.row.address }}</p>
          <div slot="reference" class="name-wrapper">
            <el-tag>{{ scope.row.name }}</el-tag>
          </div>
        </el-popover>
      </template>
    </el-table-column>
    <el-table-column label="操作">
      <template scope="scope">
        <el-button
          size="small"
          @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
        <el-button
          size="small"
          type="danger"
          @click="handleDelete(scope.$index, scope.row)">删除</el-button>
      </template>
    </el-table-column>

各种 el-table-columntemplate scope="scope 神烦,大量重复冗余不利于维护,而且还不能复用。。

于是在发现了 Egrid,解决了这个痛点

Egrid 的源码实现很简单,然后我突发奇想能不能实现 egrid + vue-data-tables 一起使用,结果改了两行 Egrid 的源码后二者完美一起使用(暂未发现 BUG),卧槽,这次真的要解放双手了

所以建议大家 egrid + vue-data-tables 一起组合使用~或者发起 PR 把 egrid 内置到 vue-data-tables 中

Expected Behavior

Current Behavior

Steps to Reproduce

Detailed Description

For feature request, provide the following section

Motivation / Use Case

Expected Behavior

Other Information

njleonzhang commented 5 years ago

可以提供你同时使用的一些例子看看么。

zaxlct commented 5 years ago

Egrid 的优势

1. 不用写 el-table-columntemplate scope="scope 等样板代码

<egrid :columns="columns"></egrid>

// 定义 columns
const columns = [
  {
    label: '日期',
    prop: 'date',
    width: 100
    ...
  },
  {
    label: '姓名',
    prop: 'name',
    minWidth: 100
    ...
  },
  ......
]

2. columns-schema 和 columns-handler 可对 columns 进行增删改操作

<egrid :columns="columns" :columnsHandler="columnsHandler"></egrid>

// columns-schema
// 通过 props 传递 Object 对 columns 进行增删改操作
{
  label: '其他',
  component: Btn, // 'el-button'
  listeners: {
    'custom-event' (data) {
      console.log('custom-event', data)
    }
  },
  propsHandler: function ({ row, col, column }) {
    return { row, col, column }
  }
  ......
}

// columns-handler
// 通过 props 传递 Function 对 columns 进行增删改操作
columnsHandler (cols) {
  return cols.concat({
    label: '操作',
    align: 'left',
    sortable: false,
    ...
    component: OperatComponent,
  })
}

3. 表格继承

少写样板代码似乎带来的兴奋不是那么大,但是通过传递对象和函数对 columns 进行增删改操作,就有很大的操作空间了,比如可以实现「表格的继承」

我可以定义一个基础的表格组件:

// base-table component
<egrid :columns="columns" :columnsHandler="columnsHandler"></egrid>

props: [columnsHandler]

const columns = [
  {
    label: '日期',
    prop: 'date',
    width: 100
    ...
  },
  {
    label: '姓名',
    prop: 'name',
    minWidth: 100
    ...
  },
  {
    label: '图片',
    component: Btn, // 'el-button'
    listeners: {
      'custom-event' (data) {
        console.log('custom-event', data)
      }
    },
    propsHandler: function ({ row, col, column }) {
      return { row, col, column }
    }
    ......
  }
  ......
]

再定义一个高级的表格组件:

<base-table :columnsHandler="columnsHandler"></base-table>

columnsHandler(cols) {
  return cols.concat({
    label: '删除',
    align: 'left',
    sortable: false,
    ...
    component: OperatComponent,
  },{
    label: '增加',
    align: 'left',
    sortable: false,
    ...
    component: OperatComponent,
  }),
  ...
}

继承 base-table 组件后,可任意传递 columns,定制高级 table

4. 高级用法

还可以继承基础组件后,传递任意事件

<base-table :columnsHandler="columnsHandler" @selection-change="xxx" row-key="xxx"></base-table>

columnsHandler (cols) {
  return cols.concat({
    label: '操作',
    align: 'center',
    component: Vue.extend({
      props: ['row'],
      render(h) {
        return (<ElButton type="text" onClick={_ => this.$emit('createProduct', this.row.id)}>新建产品</ElButton>)
      },
    }),
    listeners: {
      'createProduct' (id) {
        // 所有操作都放到父组件里实现,base-table 不受任何影响
        console.log('新建产品id')
      },
    }
  })
}
zaxlct commented 5 years ago

所以当项目使用 Egrid 后,再把 vue-data-tablesel-form-dialog 用起来,简直完美~

njleonzhang commented 5 years ago

看起来 Egrid 对 render 做了封装。

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Chill-Cool commented 4 years ago

Please follow the issue template, or your issue may be closed automatically.

For bug report, provide the following section

Online reproduce

感谢作者的 vue-data-tablesel-form-dialog,我的管理后台项目中大量使用了它们,真心舒服~省了很多代码(先舔一波😂)

不过我觉得这些加起来还是没有彻底解放双手,有个痛点没解决: 平时我们使用的 element table 时候往往是这样写的

    <el-table-column
      label="日期"
      width="180">
      <template scope="scope">
        <el-icon name="time"></el-icon>
        <span style="margin-left: 10px">{{ scope.row.date }}</span>
      </template>
    </el-table-column>
    <el-table-column
      label="姓名"
      width="180">
      <template scope="scope">
        <el-popover trigger="hover" placement="top">
          <p>姓名: {{ scope.row.name }}</p>
          <p>住址: {{ scope.row.address }}</p>
          <div slot="reference" class="name-wrapper">
            <el-tag>{{ scope.row.name }}</el-tag>
          </div>
        </el-popover>
      </template>
    </el-table-column>
    <el-table-column label="操作">
      <template scope="scope">
        <el-button
          size="small"
          @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
        <el-button
          size="small"
          type="danger"
          @click="handleDelete(scope.$index, scope.row)">删除</el-button>
      </template>
    </el-table-column>

各种 el-table-columntemplate scope="scope 神烦,大量重复冗余不利于维护,而且还不能复用。。

于是在发现了 Egrid,解决了这个痛点

Egrid 的源码实现很简单,然后我突发奇想能不能实现 egrid + vue-data-tables 一起使用,结果改了两行 Egrid 的源码后二者完美一起使用(暂未发现 BUG),卧槽,这次真的要解放双手了

所以建议大家 egrid + vue-data-tables 一起组合使用~或者发起 PR 把 egrid 内置到 vue-data-tables 中

Expected Behavior

Current Behavior

Steps to Reproduce

Detailed Description

For feature request, provide the following section

Motivation / Use Case

Expected Behavior

Other Information

用一行<el-table-column v-for="(col, i) in columns" :key="i" v-bind="col"></el-table-column>可以解决hard-code column的问题