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 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-pro-table

v1.1.1

Published

一个基于ElementUI封装的table列表页组件,将包含搜索、列表、分页等功能的页面封装成一个组件

Downloads

7

Readme

vue-pro-table

本组件是基于 vue2 开发,如果你正在使用 vue3,请点击vue3-pro-table查看 vue3 版的 pro-table 组件

一个基于 ElementUI 封装的 table 列表页组件,将包含搜索、列表、分页等功能的页面封装成一个组件

特性

  • 将搜索、列表、分页三者的交互逻辑封装到组件中,节省开发者代码量
  • 配置化的请求函数,自动发送请求,自动获取请求参数,自动显示 loading 效果
  • 配置化的表格项,跟 el-table-column 的配置属性类似
  • 配置化的搜索表单,支持大部分表单元素
  • 配置化的分页,跟 el-pagination 的配置属性类似
  • 自定义是否显示搜索和分页
  • 自定义标题栏和工具栏
  • 丰富的插槽提供功能扩展

使用

安装和引入

安装

// npm
npm install vue-pro-table
// yarn
yarn add vue-pro-table

引入

该组件依赖 element-ui,需要自行引入

import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.use(ElementUI);
// 引入vue-pro-table
import VueProTable from "vue-pro-table";
Vue.use(VueProTable);

快速使用

<template>
  <vue-pro-table title="列表" :request="getList" :columns="columns">
    <template #operate="scope">
      <el-button size="mini" type="primary">编辑</el-button>
      <el-button size="mini" type="danger">删除</el-button>
    </template>
  </vue-pro-table>
</template>

<script>
import {getUserList} from 'src/api/xxx';
export default {
  data() {
    // 表格列配置,大部分属性跟el-table-column配置一样
    columns: [
      { label: '序号', type: 'index' },
      { label: '名称', prop: 'nickName', width: 180 },
      { label: '邮箱', prop: 'userEmail' },
      {
        label: '操作',
        fixed: 'right',
        width: 180,
        align: 'center',
        tdSlot: 'operate', // 自定义单元格内容的插槽名称
      },
    ],
  },
  methods: {
    // 请求函数
    async getList(params) {
      // params是从组件接收的,包含分页和搜索字段。
      const { data } = await getUserList(params)

      // 必须要返回一个对象,包含data数组和total总数
      return {
        data: data.list,
        total: +data.total,
      }
    },
  }
}
</script>

预览效果

默认不包含搜索表单

列表页

请求函数配置

  • request,请求列表数据的函数

    组件加载的时候会自动执行 request 函数,并在加载过程中显示 loading 效果

    • 函数接收参数:包含搜索表单的所有字段和分页的 pageNum 和 pageSize

    • 函数必须返回一个对象,包含:

      • data: 列表数据的数组
      • total:总数,用于分页

表格配置

  • border 表格是否有边框。布尔值,默认为 false

  • columns 属性的配置,是一个数组

| 参数 | 说明 | 类型 | 可选值 | 默认值 | | --------- | ------------------------------------------------------------------------------------------- | ---------------------- | ---------------------- | ------ | | label | 对应 el-table-column 的 label | string | - | - | | type | 对应 el-table-column 的 type | string | selection/index/expand | - | | prop | 对应 el-table-column 的 prop | string | - | - | | width | 对应 el-table-column 的 width | string,number | - | - | | minWidth | 对应 el-table-column 的 min-width | string,number | - | - | | align | 对应 el-table-column 的 align | string | left/center/right | left | | fixed | 对应 el-table-column 的 fixed | string, boolean | true, left, right | - | | sortable | 对应 el-table-column 的 sortable | boolean | false/true | false | | filters | 对应 el-table-column 的 filters | Array[{ text, value }] | - | - | | tdSlot | 单元格要自定义内容时,可以通过此属性配置一个插槽名称,并且是作用域插槽,可以接收 scope 数据 | string | - | - | | labelSlot | 表头要自定义内容时,可以通过此属性配置一个插槽名称,并且是作用域插槽,可以接收 scope 数据 | string | - | - |

  • row-key 属性配置

    对应 el-table 的 row-key,默认值是'id'

搜索配置

  • search 属性的配置,是一个对象

    如果不想显示搜索表单,可以不配置 search 或者 search 设置为 false

| 参数 | 说明 | 类型 | 可选值 | 默认值 | | ---------- | ----------------------------------------------------------------------------------------- | ----------------- | ------ | ------ | | labelWidth | label 文字长度 | string | - | - | | inputWidth | 表单项长度 | string | - | - | | fields | 表单字段列表,包含 text,select,radio,checkbox,datetime 等类型,所有字段类型配置见下表 | Array[{字段类型}] | - | - |

  • fields 列表的字段类型配置

| 参数 | 说明 | 类型 | 可选值 | 默认值 | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- | ------ | | type | 字段类型 | string | text,textarea,select,radio,radio-button,checkbox,checkbox-button,number,date,daterange,datetime,datetimerange | text | | label | label 文本 | string | - | - | | name | 搜索时的提交的参数名称 | string | - | - | | style | 额外的样式 | object | - | - | | defaultValue | 默认值 | - | - | | | options | 当 type 是 select,radio,radio-button,checkbox,checkbox-button 时的枚举选项 | Array[{name, value}] | - | - | | filterable | 当 type 是 select 时,下拉框是否支持模糊搜索 | boolean | true, false | false | | multiple | 当 type 是 select 时,下拉框是否支持多选 | boolean | true, false | false | | transform | 搜索前对表单数据进行转换,比如表单数据是数组,但是搜索的时候需要传递字符串。它是一个函数,默认参数是字段的 value,需要返回转换后的结果 | function(value) | - | - | | trueNames | 当 type 是 daterange,datetimerange 时,开始时间和结束时间是在一个数组里面,但是搜索时可能需要两个字段,这时就需要把开始时间和结束时间分别赋值给两个字段,这两个字段的名称就是通过 trueNames 配置,它是一个数组,例如:trueNames: ['startTime', 'endTime'] | Array[string] | | | | min | 当 type 是 number 时的最小值 | number | - | - | | max | 当 type 是 number 时的最大值 | number | - | - |

分页配置

  • pagination 属性的配置,是一个对象

    如果不想显示分页,将 pagination 设置为 false

| 参数 | 说明 | 类型 | 可选值 | 默认值 | | --------- | ---------------------------- | ------------- | --------------------------------------- | --------------------------------------- | | layout | 组件布局 | string | total, sizes, prev, pager, next, jumper | total, sizes, prev, pager, next, jumper | | pageSize | 每页显示条目个数 | number | - | 10 | | pageSizes | 每页显示个数选择器的选项设置 | Array[number] | - | [10, 20, 30, 40, 50, 100] |

标题栏配置

表格上方有一个标题栏,标题栏左侧显示一个标题,右侧是一个可自定义的工具栏

  • hide-title-bar

    是否隐藏标题栏,布尔值

  • title

    表格标题

  • 自定义表格标题

    提供一个具名插槽 title,来自定义标题的内容

  • 工具栏

    工具栏默认是空的,提供一个具名插槽 toolbar,来自定义工具栏的内容

事件

  • selectionChange

    如果 columns 中配置了 type 为 selection 的列,可以通过该事件得到已选择的行,参数是一个数组

组件内部方法

  • refresh

    配置 ref 属性,可以通过 ref 获取组件后调用组件内部的refresh方法刷新列表

完整用法

<template>
  <vue-pro-table
    ref="proTable"
    title="用户列表"
    :request="getList"
    :columns="columns"
    :search="searchConfig"
    :pagination="paginationConfig"
    @selectionChange="handleSelectionChange"
  >
    <!-- 工具栏 -->
    <template #toolbar>
      <el-button
        type="primary"
        icon="el-icon-plus"
        @click="$router.push({ name: 'userAdd' })"
        >创建账号</el-button
      >
      <el-button
        type="danger"
        icon="el-icon-refresh"
        @click="$refs.proTable.refresh()"
        >刷新</el-button
      >
    </template>

    <!-- 展开行 -->
    <template #expand="{ row }">
      {{ row.userEmail }}
    </template>

    <!-- 状态 -->
    <template #status="{ row }">
      <el-tag :type="+row.status === 1 ? 'success' : 'info'">{{
        +row.status === 1 ? "启用" : "停用"
      }}</el-tag>
    </template>

    <!-- 表格操作栏 -->
    <template #page-operate="{ row }">
      <el-button
        type="text"
        @click="
          $router.push({
            name: 'userEdit',
            params: {
              id: row.id,
            },
          })
        "
        >编辑</el-button
      >

      <el-button
        v-if="+row.status === 1"
        type="text"
        @click="setUserStatus(row, 0)"
        >停用</el-button
      >

      <el-button v-else type="text" @click="setUserStatus(row, 1)"
        >启用</el-button
      >
    </template>

    <!-- 操作栏头部 -->
    <template #th-operate>
      <el-input />
    </template>
  </vue-pro-table>
</template>

<script>
import {getUserList} from 'src/api/xxx';
export default {
  data() {
    // 表格列配置,大部分属性跟el-table-column配置一样
    columns: [
        { label: '', type: 'expand', tdSlot: 'expand' },
        { label: '全选', type: 'selection' },
        { label: '序号', type: 'index' },
        { label: '账户名称', prop: 'nickName', sortable: true },
        { label: '账号', prop: 'userEmail', width: 80 },
        {
          label: '状态',
          prop: 'status',
          tdSlot: 'status',
          filters: [
            { text: '启用', value: 1 },
            { text: '禁用', value: 0 },
          ],
        },
        { label: '创建时间', prop: 'createTime', align: 'right' },
        { label: '最后修改时间', prop: 'updateTime' },
        {
          label: '操作',
          labelSlot: 'th-operate',
          fixed: 'right',
          width: 180,
          align: 'center',
          tdSlot: 'page-operate',
        },
    ],
    // 搜索配置
    searchConfig: {
        labelWidth: '90px',
        inputWidth: '360px',
        fields: [
          {
            type: 'text',
            label: '账户名称',
            name: 'nickName',
            defaultValue: 'abc',
          },
          {
            type: 'textarea',
            label: '描述',
            name: 'description',
          },
          {
            label: '状态',
            name: 'status',
            type: 'select',
            defaultValue: 1,
            options: [
              {
                name: '已发布',
                value: 1,
              },
              {
                name: '未发布',
                value: 0,
              },
            ],
          },
          {
            label: '性别',
            name: 'sex',
            type: 'radio',
            options: [
              {
                name: '男',
                value: 1,
              },
              {
                name: '女',
                value: 0,
              },
            ],
          },
          {
            label: '城市',
            name: 'city',
            type: 'radio-button',
            options: [
              {
                name: '北京',
                value: 'bj',
              },
              {
                name: '上海',
                value: 'sh',
              },
              {
                name: '广州',
                value: 'gz',
              },
              {
                name: '深圳',
                value: 'sz',
              },
            ],
          },
          {
            label: '爱好',
            name: 'hobby',
            type: 'checkbox',
            defaultValue: ['吃饭'],
            options: [
              {
                name: '吃饭',
                value: '吃饭',
              },
              {
                name: '睡觉',
                value: '睡觉',
              },
              {
                name: '打豆豆',
                value: '打豆豆',
              },
            ],
            transform: (val) => val.join(','),
          },
          {
            label: '水果',
            name: 'fruit',
            type: 'checkbox-button',
            options: [
              {
                name: '苹果',
                value: '苹果',
              },
              {
                name: '香蕉',
                value: '香蕉',
              },
              {
                name: '橘子',
                value: '橘子',
              },
              {
                name: '葡萄',
                value: '葡萄',
              },
            ],
            transform: (val) => val.join(','),
          },
          {
            label: '日期',
            name: 'date',
            type: 'date',
          },
          {
            label: '时间',
            name: 'datetime',
            type: 'datetime',
            defaultValue: '2020-10-10 8:00:00',
          },
          {
            label: '日期范围',
            name: 'daterange',
            type: 'daterange',
            trueNames: ['startDate', 'endDate'],
            style: { width: '360px' },
          },
          {
            label: '时间范围',
            name: 'datetimerange',
            type: 'datetimerange',
            trueNames: ['startTime', 'endTime'],
            style: { width: '360px' },
            defaultValue: ['2020-10-10 9:00:00', '2020-10-11 18:30:00'],
          },
          {
            label: '数量',
            name: 'num',
            type: 'number',
            min: 0,
            max: 10,
          },
        ],
    },
    // 分页配置
    paginationConfig: {
      layout: 'total, prev, pager, next, sizes', // 分页组件显示哪些功能
      pageSize: 5, // 每页条数
      pageSizes: [5, 10, 20, 50],
    }
  },
  methods: {
    // 请求函数
    async getList(params) {
      // params是从组件接收的,包含分页和搜索字段。
      const { data } = await getUserList(params)

      // 必须要返回一个对象,包含data数组和total总数
      return {
        data: data.list,
        total: +data.total,
      }
    },
    // 选择
    handleSelectionChange(arr) {
      console.log(arr)
    },
  }
}
</script>

效果:

完整用法