├── .browserslistrc ├── vue.config.js ├── babel.config.js ├── tests └── unit │ ├── .eslintrc.js │ └── example.spec.js ├── postcss.config.js ├── public ├── favicon.ico └── index.html ├── src ├── assets │ └── logo.png ├── api │ └── tables.js ├── store.js ├── router.js ├── App.vue ├── main.js ├── views │ ├── tableChildren.vue │ ├── page.vue │ ├── defineApi.js │ ├── dbTable.vue │ ├── Table.vue │ └── tableDome.vue └── components │ └── HelloWorld.vue ├── .editorconfig ├── .gitignore ├── .eslintrc.js ├── jest.config.js ├── package.json └── README.md /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | publicPath: './' 3 | } 4 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awfifnypm/vue-element-table/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awfifnypm/vue-element-table/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /src/api/tables.js: -------------------------------------------------------------------------------- 1 | import tableCmp from '@/views/Table.vue' 2 | const Table = { 3 | install: function (Vue) { 4 | Vue.component('v-table', tableCmp) 5 | } 6 | } 7 | export default Table 8 | -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | 9 | }, 10 | mutations: { 11 | 12 | }, 13 | actions: { 14 | 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | Vue.use(Router) 5 | 6 | export default new Router({ 7 | mode: 'hash', 8 | base: process.env.BASE_URL, 9 | routes: [ 10 | { 11 | path: '/', 12 | name: 'tableDome', 13 | component: () => import(/* webpackChunkName: "about" */ './views/tableDome.vue') 14 | } 15 | ] 16 | }) 17 | -------------------------------------------------------------------------------- /tests/unit/example.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import HelloWorld from '@/components/HelloWorld.vue' 3 | 4 | describe('HelloWorld.vue', () => { 5 | it('renders props.msg when passed', () => { 6 | const msg = 'new message' 7 | const wrapper = shallowMount(HelloWorld, { 8 | propsData: { msg } 9 | }) 10 | expect(wrapper.text()).toMatch(msg) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-cli3.0doem 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 30 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | transformIgnorePatterns: [ 14 | '/node_modules/' 15 | ], 16 | moduleNameMapper: { 17 | '^@/(.*)$': '/src/$1' 18 | }, 19 | snapshotSerializers: [ 20 | 'jest-serializer-vue' 21 | ], 22 | testMatch: [ 23 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 24 | ], 25 | testURL: 'http://localhost/', 26 | watchPlugins: [ 27 | 'jest-watch-typeahead/filename', 28 | 'jest-watch-typeahead/testname' 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import axios from 'axios' 6 | // import mixin from '@/views/mixin.js' 7 | import ElementUI from 'element-ui' 8 | import 'element-ui/lib/theme-chalk/index.css' 9 | import VueJsonp from 'vue-jsonp' 10 | import { utility } from '@/views/defineApi.js' 11 | import Table from '@/api/tables.js' 12 | 13 | Vue.use(ElementUI) 14 | Vue.prototype.axios = axios 15 | Vue.prototype.utility = utility 16 | Vue.config.productionTip = false 17 | Vue.use(VueJsonp) 18 | Vue.use(Table) 19 | 20 | new Vue({ 21 | router, 22 | store, 23 | render: h => h(App) 24 | }).$mount('#app') 25 | 26 | // Vue.mixin({ 27 | // data () { 28 | // return { 29 | // dataReady: false 30 | // } 31 | // } 32 | // }) 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-cli3.0doem", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "test:unit": "vue-cli-service test:unit" 10 | }, 11 | "dependencies": { 12 | "axios": "^0.19.0", 13 | "core-js": "^2.6.5", 14 | "element-ui": "^2.10.1", 15 | "lodash": "^4.17.14", 16 | "sortablejs": "^1.10.0", 17 | "vue": "^2.6.10", 18 | "vue-jsonp": "^0.1.8", 19 | "vue-router": "^3.0.3", 20 | "vuex": "^3.0.1" 21 | }, 22 | "devDependencies": { 23 | "@vue/cli-plugin-babel": "^3.9.0", 24 | "@vue/cli-plugin-eslint": "^3.9.0", 25 | "@vue/cli-plugin-unit-jest": "^3.9.0", 26 | "@vue/cli-service": "^3.9.0", 27 | "@vue/eslint-config-standard": "^4.0.0", 28 | "@vue/test-utils": "1.0.0-beta.29", 29 | "babel-core": "7.0.0-bridge.0", 30 | "babel-eslint": "^10.0.1", 31 | "babel-jest": "^23.6.0", 32 | "eslint": "^5.16.0", 33 | "eslint-plugin-vue": "^5.0.0", 34 | "less": "^3.0.4", 35 | "less-loader": "^4.1.0", 36 | "vue-template-compiler": "^2.6.10" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/views/tableChildren.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 46 | -------------------------------------------------------------------------------- /src/views/page.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 67 | 68 | 70 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 42 | 43 | 44 | 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VUE elementUI table 2 | 3 | ## 描述 4 | 5 | 在日常开发中,需要大量用到table组件,所以闲时就整合下 6 | 7 | 注:组件在开发中,数据来源于分页URL请求,但是在开发中,有时候接口有问题,所以利用catch失败回调后,再获取静态数据,所以如果没有接口的伙伴们,那就多等一小会,静态数据就会出来,如果用于线上项目时,一定要把静态数据去掉,把tableDome组件里面的init方法的else逻辑删掉,同时留意下page组件里的catch 8 | 9 | 如不需要二次开发,请使用npm依赖包 10 | npm i vue2-el-table 11 | 12 | vue2-el-table npm地址 https://www.npmjs.com/package/vue2-el-table 13 | 14 | **本组件集成了下列:** 15 | 16 | 组件控制参数: 17 | 如果都不需要,只需保留borderParams为空对象即可 18 | 19 | ``` 20 | borderParams: { 21 | operationStatus: true, // 是否显示操作列 22 | border: false, // 表格是否显示边框 23 | selection: true, // 多选 如果highlightCurrentRow为true,selection必为false 24 | stripe: false, // 是否显示斑马线 25 | highlightCurrentRow: false, // 单选 如果selection为true,highlightCurrentRow必为false 26 | maxHeight: 'auto', // 设置最大高度 27 | showSummary: false, // 是否合计 28 | spanMethod: null, // 行合并还是列合并 29 | index: false, // 是否显示序号 30 | emptyText: '暂无数据', // 如数据为空的提示语 31 | RowDrag: true, // 是否需要行拖拽 32 | rowKey: 'id', // RowDrag为true时,必填 填写数据唯一属性 如userId等 33 | isPage: true // 是否显示分页组件 默认为false 34 | isDefaultCheckAll: true // 是否默认全选所有数据 35 | isShowdbTable: true // 是否显示上table勾选,下table显示 必须和selection同时为true 36 | } 37 | ``` 38 | 39 | 分页参数: 40 | 必填项除外,其它都可不写 41 | ``` 42 | page: { 43 | url: '/api/prsBuckle/showBalanceDetails', // 列表请求接口 必填 44 | currentPage: 1, // 当前页 必填 45 | pageSizes: [10, 20, 30, 40, 50, 100], // 页显示个数选择器 必填 46 | pageSize: 10, // 页显示个数 必填 47 | pageInfo: {}, // 分页传参 必填 初始值可为{} 48 | background: true // 是否带有背景色的分页 默认false 49 | layout:"total, sizes, prev, pager, next, jumper" //默认为全部 50 | } 51 | ``` 52 | 53 | 表头参数: 54 | 必填项除外,其它都可不写 55 | 56 | | 名称 | 描述 | 是否必填 | 57 | | ----------- | ---------------------------------------- | -------- | 58 | | title | 标题名 | 必填 | 59 | | value | 字段名 | 必填 | 60 | | align | 对齐方式[left,center,right] | 默认center | 61 | | fixed | 固定表格 | 否 | 62 | | sortable | 是否排序[true, false, 'custom'] custom为后台排序 | 否 | 63 | | filters | 列条件查询 [{ text: '名称', value: '值' }] 值要对应表头value | 否 | 64 | | transitions | 数据转换 [{ key: '100', value: '一百' }] | 否 | 65 | | width | 单元格宽度 '180' | 否 | 66 | 67 | 68 | ​ 注:等同于使用管道过滤 如 if(params == '100') reutn '一百' else '无数据' 69 | 70 | 71 | 72 | ## How to start? 73 | 74 | ``` 75 | #安装包 76 | npm install 77 | 78 | #启动项目 79 | npm run serve 80 | ``` 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/views/defineApi.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | // 工具类封装 3 | export const utility = { 4 | // 封装elementUi table全选后数据提取 5 | /* 6 | params 需要操作的数组 7 | keyArr 需要转换的字段 ['id','memberNumber'] 8 | symbol 需要切换的字符 9 | 使用 checkAll(arr,['id','memberNumber']).id 结果1,2,3,4 10 | */ 11 | checkAll: (params, keyArr, symbol = ',') => { 12 | let paramsData = JSON.parse(JSON.stringify(params)) 13 | let returnData = {} 14 | let arrObj = {} 15 | keyArr.forEach(e => { 16 | arrObj[e] = [] 17 | }) 18 | paramsData.forEach(val => { 19 | keyArr.forEach(e => { 20 | if (val[e] != undefined) { 21 | arrObj[e].push(val[e]) 22 | } 23 | }) 24 | }) 25 | for (var key in arrObj) { 26 | returnData[key] = arrObj[key].join(symbol) 27 | } 28 | return returnData 29 | }, 30 | 31 | // 自定义时间选择,一般用于筛选的月份选择 32 | monthPackaging: (status, day = 30) => { 33 | const end = new Date() 34 | const start = new Date() 35 | let obj = { 36 | 0: start.setTime(start.getTime() - 3600 * 1000 * 24 * day), 37 | 1: end.setTime(end.getTime() + 3600 * 1000 * 24 * day) 38 | } 39 | obj[status] 40 | return [start, end] 41 | }, 42 | 43 | // 金额千位符转换 44 | // 转换数据只有一个值的,status=1代表是带两位小数点,其它即是不带小数点 45 | kilobitTransition: (level, status = '1') => { 46 | if (level != undefined && level != null) { 47 | let A = status == '1' ? Number(level).toFixed(2) : Number(level) 48 | return '¥' + (status == '1' ? (A || 0).toString().replace(/(\d{1,3})(?=(\d{3})+\.)/g, '$1,') : (A || 0).toString().replace(/(\d{1,3})(?=(\d{3}))/g, '$1,')) 49 | } else { 50 | return '¥' + (status == '1' ? '0.00' : '0') 51 | } 52 | }, 53 | 54 | // 转换数据中有多个值的,如1000,2000 55 | multiKilobitTransition: level => { 56 | if (level != undefined && level != null) { 57 | var arr = level.split(',') 58 | var arrStr = '' 59 | arr.forEach(val => { 60 | arrStr += 61 | '¥' + 62 | (Number(val).toFixed(2) || 0) 63 | .toString() 64 | .replace(/(\d{1,3})(?=(\d{3})+\.)/g, '$1,') + 65 | ',' 66 | }) 67 | return arrStr.slice(0, arrStr.length - 1) 68 | } else { 69 | return '¥' + '0.00' 70 | } 71 | }, 72 | 73 | // 信息脱敏 74 | infoDesensitization: level => { 75 | let data = level.toString() 76 | // 身份证 77 | let A = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/ 78 | let B = /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/ 79 | // 手机号码 80 | let C = /^1[34578]\d{9}$/ 81 | // 银行卡号 82 | let D = /^([1-9]{1})(\d{14}|\d{18})$/ 83 | if (C.test(data)) { 84 | return data.replace(/(\d{3})\d*(\d{4})/, '$1****$2') 85 | } else if (A.test(data) || B.test(data) || D.test(data)) { 86 | return data.replace(/(\d{4})\d*(\d{4})/, '$1*********$2') 87 | } 88 | }, 89 | 90 | // 数据管道过滤转换 91 | transitionFunction: (value, arr) => { 92 | let newValue = null 93 | for (let i = 0; i < arr.length; i++) { 94 | if (value == arr[i].key) { 95 | newValue = arr[i].value 96 | break 97 | } 98 | } 99 | return newValue 100 | } 101 | } 102 | // 接口类工具API 103 | export const requestUtility = { 104 | // 数据批量导出 post 105 | /* params = { 106 | url:'url', 107 | obj:{ids: this.idsStr}, 108 | fileName: '会员管理列表' 109 | } 110 | batchPostExport(params) 111 | */ 112 | batchPostExport: (params, suffix = 'xlsx') => { 113 | axios.post(params.url, params.obj, { 114 | responseType: 'blob' 115 | }) 116 | .then(res => { 117 | var blob = new Blob([res.data]) // 指定格式为vnd.ms-excel 118 | var downloadElement = document.createElement('a') 119 | var href = window.URL.createObjectURL(blob) // 创建下载的链接 120 | downloadElement.href = href 121 | downloadElement.download = `${params.fileName}.${suffix}` // 下载后文件名 122 | document.body.appendChild(downloadElement) 123 | downloadElement.click() // 点击下载 124 | document.body.removeChild(downloadElement) // 下载完成移除元素 125 | window.URL.revokeObjectURL(href) // 释放掉blob对象 126 | }) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/views/dbTable.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 251 | 252 | 259 | -------------------------------------------------------------------------------- /src/views/Table.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 265 | 266 | 274 | -------------------------------------------------------------------------------- /src/views/tableDome.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 344 | 345 | 348 | --------------------------------------------------------------------------------