├── assets ├── demo1.png └── demo2.jpg ├── .babelrc ├── .npmignore ├── .editorconfig ├── index.html ├── .gitignore ├── examples ├── main.js └── App.vue ├── packages ├── index.js └── el-validate-table │ ├── mixin-package-option.js │ └── index.vue ├── LICENSE ├── package.json ├── webpack.config.js └── README.md /assets/demo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemoisme/el-validate-table/HEAD/assets/demo1.png -------------------------------------------------------------------------------- /assets/demo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemoisme/el-validate-table/HEAD/assets/demo2.jpg -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env" 4 | ], 5 | "plugins":[ 6 | "@babel/plugin-transform-runtime" 7 | ] 8 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | src/ 3 | assets/ 4 | yarn.lock 5 | .babelrc 6 | .editorconfig 7 | *html 8 | LICENSE 9 | webpack.config.js 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | el-validate-table 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 复制代码 2 | .DS_Store 3 | node_modules/ 4 | *.map 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw* 23 | -------------------------------------------------------------------------------- /examples/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import ElementUI from 'element-ui'; 4 | import ElValidateTable from './../lib/el-validate-table' 5 | import 'element-ui/lib/theme-chalk/index.css' 6 | Vue.use(ElementUI) 7 | Vue.component('el-validate-table',ElValidateTable) 8 | new Vue({ 9 | render: h => h(App), 10 | }).$mount('#app') -------------------------------------------------------------------------------- /packages/index.js: -------------------------------------------------------------------------------- 1 | // Import vue component 2 | import component from './el-validate-table/index.vue' 3 | 4 | // `Vue.use` automatically prevents you from using the same plugin more than once, 5 | // so calling it multiple times on the same plugin will install the plugin only once 6 | component.install = Vue => { 7 | Vue.component(component.name, component) 8 | } 9 | 10 | // To auto-install when vue is found 11 | let GlobalVue = null 12 | if (typeof window !== 'undefined') { 13 | GlobalVue = window.Vue 14 | } else if (typeof global !== 'undefined') { 15 | GlobalVue = global.Vue 16 | } 17 | if (GlobalVue) { 18 | GlobalVue.use(component) 19 | } 20 | 21 | // To allow use as module (npm/webpack/etc.) export component 22 | export default component -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 nemo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/el-validate-table/mixin-package-option.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 扩展表单组件的 option 属性 3 | */ 4 | function controller(h, tag, props) { 5 | return h(tag, { 6 | props 7 | }) 8 | } 9 | 10 | function controllerVariation(h, tag, props) { 11 | return h( 12 | tag, 13 | { 14 | props: Object.assign({}, props, { 15 | key: props.value || props.label, 16 | label: props.value || props.label 17 | }) 18 | }, 19 | props.label 20 | ) 21 | } 22 | 23 | export default { 24 | methods: { 25 | select_opt(item) { 26 | return controller(this.$createElement, 'el-option', item) 27 | }, 28 | 29 | radioGroup_opt(item) { 30 | return controllerVariation(this.$createElement, 'el-radio', item) 31 | }, 32 | 33 | radioButton_opt(item) { 34 | return controllerVariation(this.$createElement, 'el-radio-button', item) 35 | }, 36 | 37 | checkboxGroup_opt(item) { 38 | return controllerVariation(this.$createElement, 'el-checkbox', item) 39 | }, 40 | 41 | checkboxButton_opt(item) { 42 | return controllerVariation( 43 | this.$createElement, 44 | 'el-checkbox-button', 45 | item 46 | ) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "el-validate-table", 3 | "version": "1.0.8", 4 | "private": false, 5 | "description": "a lib about table base on element-ui", 6 | "main": "lib/el-validate-table.js", 7 | "license": "MIT", 8 | "author": "nemoisme", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/nemoisme/el-validate-table.git" 12 | }, 13 | "keywords": [ 14 | "vue", 15 | "element-ui", 16 | "el-validate-table" 17 | ], 18 | "files": [ 19 | "packages", 20 | "lib" 21 | ], 22 | "scripts": { 23 | "dev": "cross-env NODE_ENV=development webpack-dev-server", 24 | "lib": "cross-env NODE_ENV=production webpack" 25 | }, 26 | "dependencies": { 27 | "element-ui": "^2.13.0", 28 | "lodash.get": "^4.4.2", 29 | "lodash.set": "^4.3.2", 30 | "vue": "^2.6.10" 31 | }, 32 | "devDependencies": { 33 | "@babel/core": "^7.2.2", 34 | "@babel/plugin-transform-runtime": "^7.2.0", 35 | "@babel/preset-env": "^7.1.0", 36 | "@babel/runtime": "^7.3.4", 37 | "babel-loader": "^8.1.0", 38 | "clean-webpack-plugin": "^3.0.0", 39 | "cross-env": "^7.0.2", 40 | "css-loader": "^3.4.2", 41 | "file-loader": "^6.0.0", 42 | "html-webpack-plugin": "^4.0.4", 43 | "style-loader": "^1.1.3", 44 | "vue-loader": "^15.9.1", 45 | "vue-style-loader": "^4.1.2", 46 | "vue-template-compiler": "^2.6.11", 47 | "webpack": "^4.42.1", 48 | "webpack-cli": "^3.3.11", 49 | "webpack-dev-server": "^3.10.3" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /examples/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpack = require('webpack') 3 | const { VueLoaderPlugin } = require('vue-loader') 4 | const HtmlWebpackPlugin = require('html-webpack-plugin') 5 | const env = process.env.NODE_ENV 6 | const isPrd = env === 'production' 7 | 8 | const devPlugins = [ 9 | new webpack.HotModuleReplacementPlugin(), 10 | new HtmlWebpackPlugin({ 11 | template: './index.html', 12 | inject: 'body', 13 | minify: { 14 | removeComments: true 15 | } 16 | }) 17 | ] 18 | 19 | 20 | module.exports = { 21 | //输入 22 | mode: env, 23 | entry: { 24 | path: !isPrd ? path.join(__dirname, './examples/main.js') : path.join(__dirname, './packages/index.js'), 25 | }, 26 | //输出 27 | output: { 28 | path: path.resolve(__dirname, isPrd ? './lib' : './dist'), 29 | filename: isPrd ? 'el-validate-table.js' : 'bundle.js', 30 | library: '[name].js', 31 | libraryTarget: 'umd', 32 | umdNamedDefine: true 33 | }, 34 | module: { 35 | rules: [ 36 | { 37 | test: /\.js$/, 38 | loader: 'babel-loader', 39 | include: [ 40 | path.resolve(__dirname, 'src'), 41 | path.resolve(__dirname, 'node_modules/element-ui/src') 42 | ], 43 | exclude: /node_modules/ 44 | }, 45 | { 46 | test: /\.vue$/, 47 | use: 'vue-loader', 48 | }, 49 | { 50 | test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/, 51 | loader: 'file-loader' 52 | }, 53 | { 54 | test: /\.css$/, 55 | use: ['vue-style-loader', 'style-loader', 'css-loader'] 56 | } 57 | ] 58 | }, 59 | // optimization:{ 60 | // minimizer:isPrd, 61 | // }, 62 | plugins: [new VueLoaderPlugin()].concat(isPrd ? [] : devPlugins), 63 | devServer: { 64 | port: 3000, 65 | host: '127.0.0.1', 66 | open: true, 67 | hot: true, 68 | overlay: { erros: true } 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # el-validate-table 2 | 3 | 基于 element-ui 封装的可编辑,可校验,可合并的表格 4 | 5 | ![07月-09-2019](./assets/demo2.jpg) 6 | 7 | ```sh 8 | yarn add el-validate-table or npm i el-validate-table 9 | ``` 10 | 11 | ## 目录 12 | 13 | * [介绍](#介绍) 14 | * [特点](#特点) 15 | * [示例](#示例) 16 | * [参数说明](#参数说明) 17 | 18 | 19 | ## 介绍 20 | 21 | **概要** 22 | 23 | `el-validate-table` 是基于[element-ui](https://github.com/ElemeFE/element)封装的**表格组件**,采用 vue 中的 render 函数写法,支持高度的可扩展性,可复用性,通过 JSON 配置即可实现,表格中的单元格编辑校验,多级表头,单元格合并。 24 | 25 | **背景** 26 | 27 | 基于 2019-4 月初某项目背景,项目中含有大量的多级表头,单元格编辑。项目初期,tempalte 中存在大量的结构代码,难以迭代,难以维护,基于此背景,为了节省时间,减少重复冗余的代码,让开发者专注业务逻辑。 28 | 29 | 30 | 31 | [⬆ Back to Top](#目录) 32 | 33 | ## 特点 34 | 35 | * 只需进行简单的配置,即可实现单元格编辑(可校验),多级表头,单元格合并等复杂功能 36 | * 支持 _ElTable_, _ElTableColumn_ 的所有的API 37 | * 支持单元格自定义校验 38 | * 单元格支持自定义组件渲染 39 | * 体验良好的校验交互 40 | 41 | [⬆ Back to Top](#目录) 42 | 43 | ## 示例 44 | 45 | 1.基本用法 46 | 47 | ```vue 48 | 53 | 164 | ``` 165 | 166 | [⬆ Back to Top](#目录) 167 | 168 | 169 | 170 | 171 | ## 参数说明 172 | 173 | - 外部参数说明 174 | 175 | | 参数 | 说明 | 类型 | 176 | |---------|------------------------------------------------------------|---------| 177 | | data | 匹配的数据,与 element-ui,el-table 用法相同 | Array | 178 | | columns | 列配置,支持 el-table-column 所有的配置项,格外扩展 config | Array | 179 | 180 | 181 | - columns 参数说明 182 | 183 | | 参数 | 说明 | 类型 | 184 | |--------------------------|------------------------------------|----------| 185 | | prop | 绑定的列字段 | string | 186 | | label | 列标题显示 | string | 187 | | children | 子级表头配置 | array | 188 | | render(h,params) | 自定义渲染元素 | function | 189 | | component | 自定义组件 | vnode | 190 | | formatter | 格式化列单元格数据 | function | 191 | 192 | - config(rowIndex,row,columnIndex,prop,column) 配置说明 193 | 194 | | 参数 | 说明 | 类型 | 195 | |----------------------|--------------------------------------|-----------| 196 | | type | 渲染的元素tag or 组件的name | stirng | 197 | | rules | 对表单元素的校验 | array | 198 | | event | 事件 | object | 199 | | style | 样式 | object | 200 | | attrs | 外部参数 | object | 201 | | ...other | Form-Item Attributes | any | 202 | 203 | [⬆ Back to Top](#目录) 204 | -------------------------------------------------------------------------------- /packages/el-validate-table/index.vue: -------------------------------------------------------------------------------- 1 | 283 | 313 | --------------------------------------------------------------------------------