npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

vue-elementui-table

v0.1.4

Published

基于element-ui表格二次包装的表格,可以使用JSON完成表格配置

Readme

介绍

在开发管理系统的时候,经常会开发大量的表格,但是直接使用element-ui的原生组件时候,不仅写法繁琐,而且自身并不具备分页,行编辑,顶部按钮等等功能,需要通过插槽或者多个组件组合才能实现,本项目是基于element-ui二次封装的表格,具体功能点见下文。

我是子君,如果觉得这个框架有用,麻烦给我一个star,谢谢,同时欢迎您关注公众号【前端有的玩】,邀你一起玩前端

主要功能

  1. 分页
  2. 顶部按钮
  3. 行编辑按钮
  4. 自带复选框
  5. 行编辑
  6. 自适应高度
  7. 链接列
  8. 插槽列
  9. 顶部按钮,行编辑按钮支持下拉按钮
  10. 其他功能

具体功能见示例

待开发功能

  1. 通过属性配置分页位置在顶部还是底部,或者顶部底部都显示
  2. 可以支持更丰富的行编辑表单组件
  3. 可以支持配置搜索功能
  4. 支持滚动加载
  5. 欢迎大家提 issues

常用命令

  1. 安装
npm install vue-elementui-table -S
  1. 在项目中使用

main.js中添加以下代码


import ZjTable from 'vue-element-table'
Vue.use(ZjTable)
  1. 查看官方示例

下载github源码,然后执行下面命令即可查看示例

npm run serve
  1. 代码格式化
npm run lint

使用说明

点击访问 https://juejin.im/post/5f1d92cb5188252e884e986f,即可查看使用说明

基本表格

只显示表头与数据

<template>
  <div style="height: 500px;">
    <zj-table :columns="columns" :data="data" :pagination="false" />
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      columns: Object.freeze([
        {
          label: '姓名',
          prop: 'name'
        },
        {
          label: '性别',
          prop: 'sex',
          // 格式化表格,与element-ui 的表格属性相同
          formatter(row, column, cellValue) {
            return cellValue === 1 ? '男' : '女'
          }
        },
        {
          label: '年龄',
          prop: 'age'
        }
      ]),
      data: [
        {
          name: '子君',
          sex: 1,
          age: 18
        }
      ],
      // 是否显示多选框
      selectable: true,
      // 是否显示序号列
      sequence: true
    }
  }
}
</script>

使用分页

<template>
  <zj-table
    v-loading="loading"
    :columns="columns"
    :data="data"
    :current-page.sync="currentPage"
    :page-size.sync="pageSize"
    :total="total"
    height="auto"
    @page-change="$_handlePageChange"
  />
</template>
<script>
export default {
  data() {
    return {
      columns: Object.freeze([
        {
          label: '姓名',
          prop: 'name'
        },
        {
          label: '性别',
          prop: 'sex',
          // 格式化表格,与element-ui 的表格属性相同
          formatter(row, column, cellValue) {
            return cellValue === 1 ? '男' : '女'
          }
        },
        {
          label: '年龄',
          prop: 'age'
        }
      ]),
      data: [],
      // 当前页码
      currentPage: 1,
      // 每页条数
      pageSize: 10,
      // 总条数
      total: 0,
      loading: false
    }
  },
  created() {
    this.loadData()
  },
  methods: {
    // 加载表格数据
    loadData() {
      this.loading = true
      setTimeout(() => {
        this.total = 40
        const { currentPage, pageSize } = this
        this.data = new Array(pageSize).fill({}).map((item, index) => {
          return {
            name: `子君${currentPage + (index + 1) * 10}`,
            sex: Math.random() > 0.5 ? 1 : 0,
            age: Math.floor(Math.random() * 100)
          }
        })
        this.loading = false
      }, 1000)
    },
    $_handlePageChange() {
      // 因为上面设置属性指定了.sync,所以这两个属性会自动变化
      console.log(this.pageSize, this.currentPage)
      this.loadData()
    }
  }
}
</script>

使用顶部按钮与行操作按钮

<template>
  <zj-table
    v-loading="loading"
    :columns="columns"
    :data="data"
    :current-page.sync="currentPage"
    :page-size.sync="pageSize"
    :total="total"
    :buttons="buttons"
    @page-change="$_handlePageChange"
  />
</template>
<script>
export default {
  data() {
    return {
      columns: Object.freeze([
        {
          // 可以指定列的宽度,与element-ui原生用法一致
          width: 220,
          label: '姓名',
          prop: 'name'
        },
        {
          label: '性别',
          prop: 'sex',
          // 格式化表格,与element-ui 的表格属性相同
          formatter(row, column, cellValue) {
            return cellValue === 1 ? '男' : '女'
          }
        },
        {
          label: '年龄',
          prop: 'age'
        },
        {
          label: '公众号',
          prop: 'officialAccount'
        },
        // 行编辑按钮,在表格末尾出现,自动锁定右侧
        {
          width: 180,
          label: '操作',
          actions: [
            {
              id: 'follow',
              text: '关注作者',
              click: this.$_handleFollowAuthor
            },
            {
              id: 'edit',
              text: '编辑',
              // 可以通过before控制按钮是否显示,比如下面年龄四十岁的才会显示编辑按钮
              before(row) {
                return row.age < 40
              },
              click: this.$_handleEdit
            },
            {
              id: 'delete',
              text: '删除',
              icon: 'el-icon-delete',
              disabled(row) {
                return row.sex === 0
              },
              // 为了拿到this,这里需要用箭头函数
              click: () => {
                this.$alert('女生被禁止删除了')
              }
            }
          ]
        }
      ]),
      data: [],
      // 当前页码
      currentPage: 1,
      // 每页条数
      pageSize: 10,
      // 总条数
      total: 0,
      loading: false,
      buttons: Object.freeze([
        {
          // id 必须有而且是在当前按钮数组里面是唯一的
          id: 'add',
          text: '新增',
          type: 'primary',
          icon: 'el-icon-circle-plus',
          click: this.$_handleAdd
        },
        {
          id: 'delete',
          text: '删除',
          // rows 是表格选中的行,如果没有选中行,则禁用删除按钮, disabled可以是一个boolean值或者函数
          disabled: rows => !rows.length,
          click: this.$_handleRemove
        },
        {
          id: 'auth',
          text: '这个按钮根据权限显示',
          // 可以通过返回 true/false来控制按钮是否显示
          before: (/** rows */) => {
            return true
          }
        },
        {
          id: 'dropdown',
          text: '下拉按钮',
          children: [
            {
              id: 'moveUp',
              text: '上移',
              icon: 'el-icon-arrow-up',
              click: () => {
                console.log('上移')
              }
            },
            {
              id: 'moveDown',
              text: '下移',
              icon: 'el-icon-arrow-down',
              disabled: rows => !rows.length,
              click: () => {
                console.log('下移')
              }
            }
          ]
        }
      ])
    }
  },
  created() {
    this.loadData()
  },
  methods: {
    // 加载表格数据
    loadData() {
      this.loading = true
      setTimeout(() => {
        this.total = 40
        const { currentPage, pageSize } = this
        this.data = new Array(pageSize).fill({}).map((item, index) => {
          return {
            id: currentPage + (index + 1) * 10,
            name: `子君${currentPage + (index + 1) * 10}`,
            sex: Math.random() > 0.5 ? 1 : 0,
            age: Math.floor(Math.random() * 100),
            officialAccount: '前端有的玩'
          }
        })
        this.loading = false
      }, 1000)
    },
    $_handlePageChange() {
      // 因为上面设置属性指定了.sync,所以这两个属性会自动变化
      console.log(this.pageSize, this.currentPage)
      this.loadData()
    },
    // 新增
    $_handleAdd() {
      this.$alert('点击了新增按钮')
    },
    // 顶部按钮会自动将表格所选的行传出来
    $_handleRemove(rows) {
      const ids = rows.map(({ id }) => id)
      this.$alert(`要删除的行id为${ids.join(',')}`)
    },
    // 关注作者公众号
    $_handleFollowAuthor() {
      const image = require('../../assets/qrcode.png')
      const h = this.$createElement
      this.$msgbox({
        title: '扫码关注',
        message: h('img', {
          attrs: {
            src: image
          },
          style: {
            width: '400px'
          }
        })
      })
    },
    /**
     * row 这一行的数据
     */
    $_handleEdit(row, column) {
      console.log(row, column)
      this.$alert(`点击了姓名为【${row.name}】的行上的按钮`)
    }
  }
}
</script>

按钮使用插槽

<template>
  <zj-table
    v-loading="loading"
    :columns="columns"
    :data="data"
    :current-page.sync="currentPage"
    :page-size.sync="pageSize"
    :total="total"
    :buttons="buttons"
    @page-change="$_handlePageChange"
  >
    <template #button="{id}">
      <template v-if="id === 'slot'">
        <el-button>
          自定义顶部按钮
        </el-button>
      </template>
    </template>

    <template #action="{id}">
      <template v-if="id === 'slot'">
        <el-button type="text">
          自定义操作按钮
        </el-button>
      </template>
    </template>
  </zj-table>
</template>
<script>
export default {
  data() {
    return {
      columns: Object.freeze([
        {
          // 可以指定列的宽度,与element-ui原生用法一致
          width: 220,
          label: '姓名',
          prop: 'name'
        },
        {
          label: '性别',
          prop: 'sex',
          // 格式化表格,与element-ui 的表格属性相同
          formatter(row, column, cellValue) {
            return cellValue === 1 ? '男' : '女'
          }
        },
        {
          label: '年龄',
          prop: 'age'
        },
        {
          label: '公众号',
          prop: 'officialAccount'
        },
        // 行编辑按钮,在表格末尾出现,自动锁定右侧
        {
          width: 220,
          label: '操作',
          actions: [
            {
              id: 'follow',
              text: '关注作者',
              click: this.$_handleFollowAuthor
            },
            {
              id: 'slot',
              useSlot: true
            }
          ]
        }
      ]),
      data: [],
      // 当前页码
      currentPage: 1,
      // 每页条数
      pageSize: 10,
      // 总条数
      total: 0,
      loading: false,
      buttons: Object.freeze([
        {
          // id 必须有而且是在当前按钮数组里面是唯一的
          id: 'add',
          text: '新增',
          type: 'primary',
          icon: 'el-icon-circle-plus',
          click: this.$_handleAdd
        },
        {
          id: 'slot',
          useSlot: true
        }
      ])
    }
  },
  created() {
    this.loadData()
  },
  methods: {
    // 加载表格数据
    loadData() {
      this.loading = true
      setTimeout(() => {
        this.total = 40
        const { currentPage, pageSize } = this
        this.data = new Array(pageSize).fill({}).map((item, index) => {
          return {
            id: currentPage + (index + 1) * 10,
            name: `子君${currentPage + (index + 1) * 10}`,
            sex: Math.random() > 0.5 ? 1 : 0,
            age: Math.floor(Math.random() * 100),
            officialAccount: '前端有的玩'
          }
        })
        this.loading = false
      }, 1000)
    },
    $_handlePageChange() {
      // 因为上面设置属性指定了.sync,所以这两个属性会自动变化
      console.log(this.pageSize, this.currentPage)
      this.loadData()
    },
    // 新增
    $_handleAdd() {
      this.$alert('点击了新增按钮')
    }
  }
}
</script>

表格行编辑

<template>
  <zj-table
    ref="table"
    :columns="columns"
    :data="data"
    :pagination="false"
    :selectable="selectable"
    :sequence="sequence"
  />
</template>
<script>
export default {
  data() {
    return {
      columns: Object.freeze([
        {
          label: '姓名',
          prop: 'name',
          editable: true,
          field: {
            componentType: 'input',
            rules: [
              {
                required: true,
                message: '请输入姓名'
              }
            ]
          }
        },
        {
          label: '性别',
          prop: 'sex',
          // 格式化表格,与element-ui 的表格属性相同
          formatter(row, column, cellValue) {
            return cellValue === '1' ? '男' : '女'
          },
          editable: true,
          field: {
            componentType: 'select',
            options: [
              {
                label: '男',
                value: '1'
              },
              {
                label: '女',
                value: '0'
              }
            ]
          }
        },
        {
          label: '年龄',
          prop: 'age',
          editable: true,
          field: {
            componentType: 'number'
          }
        },
        {
          label: '操作',
          actions: [
            {
              id: 'edit',
              text: '编辑',
              before: row => {
                return !this.editIds.includes(row.id)
              },
              click: this.$_handleEdit
            },
            {
              id: 'save',
              text: '保存',
              before: row => {
                return this.editIds.includes(row.id)
              },
              click: this.$_handleSave
            }
          ]
        }
      ]),
      data: [
        {
          // 行编辑必须指定rowKey字段,默认是id,如果修改为其他字段,需要给表格指定row-key="字段名"
          id: '0',
          name: '子君',
          sex: '1',
          age: 18
        },
        {
          // 行编辑必须指定rowKey字段,默认是id,如果修改为其他字段,需要给表格指定row-key="字段名"
          id: '1',
          name: '子君1',
          sex: '0',
          age: 18
        }
      ],
      // 是否显示多选框
      selectable: true,
      // 是否显示序号列
      sequence: true,
      editIds: []
    }
  },
  methods: {
    $_handleEdit(row) {
      // 通过调用 startEditRow 可以开启行编辑
      this.$refs.table.startEditRow(row.id)
      // 记录开启了行编辑的id
      this.editIds.push(row.id)
    },
    $_handleSave(row) {
      this.$refs.table.endEditRow(row.id, (valid, result, oldRow) => {
        if (valid) {
          console.log('修改之后的数据', result)
          console.log('原始数据', oldRow)
          const index = this.editIds.findIndex(item => item === row.id)
          this.editIds.splice(index, 1)
        } else {
          // 如果校验失败,则返回校验的第一个输入框的异常信息
          console.log(result)
          this.$message.error(result.message)
        }
      })
    }
  }
}

API

表格属性

| 参数 | 说明 | 类型 | 默认值 | -|-|-|- | columns | 表格列,详见字段属性说明 | Array<Object> | [] | buttons| 表格上方的按钮,详见按钮字符说明| Array<Object> | [] | pagination | 是否启用分页 | Boolean | false | pageSize | 分页后每页条数 | Number | 10 | total | 分页后数据总条数 | Number | 0 | currentPage | 分页后当前页码 | Number | 0 | selectable | 表格是否显示复选框 | Boolean | true | sequence | 表格前是否显示序号列 | Boolean | false | height | 表格高度,只有在特定情况下使用 | Number | String | auto

表格事件

表格除了以下事件外,可以使用element ui 表格组件的其他所有事件 | 事件名 | 说明 | 参数 -|-|- | page-change | 用户修改分页条数,页码等触发 | - | selection-change | 用户修改复选框选中的行时触发 | selection: 选中的行数据 | current-change | 用户点击行时触发 | current: 点击的行数据 | sort-change | 在启用表头排序后排序状态发生变化触发 | -

表格方法

| 方法名 | 说明 | 参数 | 返回值 -|-|-|- | startEditRow | 开始行编辑 | index: 编辑的行索引 | - | endEditRow | 结束行编辑 | callback(valid, data, rows): 回调函数, valid: 行编辑验证是否成功 data: 验证成功行编辑数据,失败时为失败原因 rows: 编辑的这一行的原始数据| - | isEditRow | 当前表格是否正在行编辑 | - | result:Boolean | cancelEditRow | 取消行编辑 | - | - | getSelectionRows | 获取复选框选中的行 | - | rows:Array<row> | | getCurrentRow | 获取点击行选中的行 | - | row:Object | setCurrentRow | 单行选中时设置选中的行 | row:Object| - | getEditFieldValues | 获取正在编辑的行的数据 | - | data:Object | setEditFieldValues | 设置正在编辑行的数据 | data:Object | - | toggleRowSelection | 启用复选后切换行的选中状态 | row: Object, select: Boolean | - | doLayout | 重新布局表格,当表格父容器由隐藏状态变为显示时,可能表格布局会错乱 | - | -

内置插槽

| 插槽 | 说明 | 参数 | -|-|- | column | 表格列插槽,可以自定义表格列渲染方式 | {row,column,prop,cellValue,$index,field} field为行编辑字段信息 | header | 自定义表格表头显示方式 | {label,prop,column, $index, field } | button | 自定义表头顶部按钮 | {button, selectedRow} selectedRow为选中的表格行数据 | toolbar| 自定义顶部工具条, 工具条会放在左侧按钮与右侧搜索区域中间 | -

列属性

列属性除以下属性外,elementui 列其他属性均可使用

| 参数 | 说明 | 类型 | 默认值 | -|-|-|- | label | 列名 | String | - | prop | 列属性 | String | - | width | 表头宽度 | Number | - | sortable | 是否排序列 | Boolean | false | formatter | 单个元格式化 | (row,column,cellValue):String| - | nests | 嵌套列 | Array<Column> | - | events | 单元格事件,见elementui单元格事件 | Object<Event> | - | actions | 操作列,详见操作列属性 | Array<Object> | - | editable | 是否可编辑行 | Boolean | false | field | 行编辑字符,详见行编辑字段属性 | Object | - | beforeEdit | 当前单元格开启编辑时调用,返回true则开启编辑 | (row,column,cellValue,index):Boolean |useSlot | 是否在当前列使用插槽,插槽名称为 column | Boolean | false | hidden | 是否隐藏当前列 | Boolean|Function | false

表头按钮属性

表头按钮除以下属性外,elementui 按钮其他属性均可使用 | 参数 | 说明 | 类型 | 默认值 | -|-|-|- | id | 按钮唯一标识,必填 | String|Number | - | text| 按钮显示文字 | String | - | icon | 按钮显示图标 | String | - | click | 点击按钮事件,传入选中的行数据 | (rows):void | -

行操作按钮属性

| 参数 | 说明 | 类型 | 默认值 | -|-|-|- | id | 按钮唯一标识,必填 | String|Number | - | text | 按钮冒泡显示的文字 | String | - | icon | 按钮图标,必填 | String | - | before | 按钮渲染前调用,返回false不渲染按钮 | (row,column,index):Boolean | - | click | 点击按钮事件 | (row,column,index):void | -