├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── dist ├── build.js ├── crud.common.js ├── element-icons.ttf └── element-icons.woff ├── example ├── info - 01 │ ├── App.vue │ ├── main.js │ └── xhr │ │ └── index.js └── info inline - 02 │ ├── App.vue │ ├── main.js │ └── xhr │ └── index.js ├── index.html ├── package.json ├── src ├── Crud.vue ├── CrudInline.vue ├── fieldType.js ├── index.js ├── mixins │ └── Simple.js └── report.js ├── webpack.config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], "stage-2" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 志 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Unfortunately, this repository is not maintained anymore, use it at your own risk. 2 | 3 | 说明:这个项目在组件的实现上可能有一些问题,且时过境迁,Vue 框架及 element UI 库的版本可能也发生了更新,不一定适合于当下以及将来。 4 | 5 | # vue-element-crud 6 | 7 | > A wrapped vue CRUD component based on the famous vue UI componets -- element-ui. 8 | 9 | > 一款基于 `element-ui` 组件的增删改查组件。 10 | 11 | Here is a simple [demo](https://rawgit.com/wisetc/vue-element-crud/master/index.html). 12 | 13 | 您可以阅读项目中的示例 [examples](example) 和源码文件 [Crud.vue](src/Crud.vue) 来帮助您理解组件的具体用法。 14 | 15 | ## Local development 16 | 17 | You can download or clone this repository as long as you like it. Then you can run npm scripts 18 | 19 | ```bash 20 | $ npm install 21 | $ npm run dev 22 | ``` 23 | 24 | Open a new terminal, 25 | 26 | ```bash 27 | $ npm run build:watch 28 | ``` 29 | 30 | ## Usage 31 | 32 | You can use vue-element-crud as a vue plugin or as a vue component. 33 | 34 | If you'd like to treat it as a componet. You can import CRUD as components. 35 | 36 | ### As component 37 | 38 | ```javascript 39 | import { CRUD } from 'vue-element-crud' 40 | 41 | export default { 42 | components: { 'crud': CRUD } 43 | } 44 | ``` 45 | Otherwise, you can treat it as a plugin. 46 | 47 | ### As Plugin 48 | 49 | #### Step-1, init project 50 | 51 | You may need to init a vue project or take a existing one to continue as vue-loader or babel-loader or css-loader is required for element-ui. 52 | 53 | ```bash 54 | $ vue init webpack 55 | ``` 56 | 57 | #### Step-2, install 58 | 59 | This component is dependent on element-ui, and `element-ui` will automatically installed when you install `vue-element-crud`, so you don't have to install `element-ui` in addition. 60 | 61 | ```bash 62 | $ npm install -S vue-element-crud 63 | ``` 64 | 65 | #### Step-3, vue use 66 | 67 | Add these lines below to your main.js 68 | 69 | ```javascript 70 | import 'element-ui/lib/theme-default/index.css' 71 | import ElementUI from 'element-ui' 72 | import CRUD from 'vue-element-crud' 73 | 74 | Vue.use(ElementUI) 75 | Vue.use(CRUD) 76 | ``` 77 | 78 | #### Step-4, refer to examples 79 | 80 | You can read the docs or [examples](example) to find out how to implement props and methods of this vue-element-crud. 81 | 82 | ### API 83 | 84 | | props | type | required | default | description | 85 | |:---:|:---:|:---:|:---:|:---:| 86 | | data | Array | true | --- | Table data array | 87 | | form | Object | true | --- | Form object to store form item varaibles | 88 | | fields | Object | true | --- | Object that describes form items structure. eg. `{ name: { label: 'name', length: 20, type: String, options: [{ label: 'Mike', value: 'Mike' }] }` | 89 | | rules | Object | false | --- | Object that describes form items rules. eg. `{ name: [{ required: true, message: 'name is required.' }] }` | 90 | | size | String | false | `'large'` | Size the dialog. `'full'` or `'large'` or `small` or omitted. | 91 | | labelWidth | String | false | `'100px'` | Label width of form and table. | 92 | | inline | Boolean | false | `false` | Determine whether form items live inline or not. | 93 | | table | Object | false | --- | If table structure is not according to the form structure, you can specify it. eg. `{ name: 'name' }`| 94 | | actions | Array | false | `['create', 'destroy', 'update']` | The crud actions.| 95 | | loading | Boolean | false | `false` | CRUD is in XHR state. Submit button was disabled if true.| 96 | | highlightCurrentRow | Boolean | false | `false` | Highlight table current row or not. | 97 | | rowStyle | Function | false | --- | Table row style function. `Function(row, index)`| 98 | 99 | | events | description | 100 | |:---:|:---:| 101 | | open | dialog open event. set `editing` to true to show the dialog. | 102 | | close | dialog close event. set `editing` to false to close the dialog. | 103 | | create | form create event. You need to assign form model to the `form`. | 104 | | update | form update event. `(row, index)` passed to the handler. You need to assign row to the `form`. | 105 | | destroy | table row destory event. `(row, index)` passed to the handler. | 106 | | submit | form submit event. `(status, closeDialog)` passed to the handler. `0` stands for creating, and `1` stands for updating. `closeDialog` is a function. | 107 | | expand | table expand event. `(row, expanded)` passed to the handler. See element-ui table events. | 108 | | row-click | table row click event. `(row, event, column)` passed to the handler. See element-ui table events. | 109 | | row-dblclick | table row dblclick event. `(row, event)` passed to the handler. See element-ui table events. | 110 | 111 | | slots | description | 112 | |:---:|:---:| 113 | | index | Table row index slot. See element-ui table slots. | 114 | | expand | Table expand slot. See element-ui table slots. | 115 | | prepend | Table prepend slot. | 116 | | default | Table append slot. | 117 | | addon | Form addon slot. | 118 | 119 | Your template may look like this. 120 | 121 | ```template 122 | 125 | ``` 126 | 127 | Here is a [simple mixin](src/mixins) that may help you to bootstrap it. Just import `Simple`. 128 | 129 | ```javascript 130 | import { Simple } from 'vue-element-crud' 131 | 132 | export { 133 | mixins: [Simple] 134 | } 135 | ``` 136 | 137 | ## Contribute 138 | 139 | If you have some ideas about this component, please don't hesitate to let us konw. You can make a new issue to make it better. 140 | -------------------------------------------------------------------------------- /dist/crud.common.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("element-ui")):"function"==typeof define&&define.amd?define(["element-ui"],t):"object"==typeof exports?exports.CRUD=t(require("element-ui")):e.CRUD=t(e["element-ui"])}(this,function(e){return function(e){function t(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/dist/",t(t.s=9)}([function(e,t,r){"use strict";function n(){for(var e=arguments.length,t=Array(e),r=0;r=o)return e;switch(e){case"%s":return String(t[n++]);case"%d":return Number(t[n++]);case"%j":try{return JSON.stringify(t[n++])}catch(e){return"[Circular]"}break;default:return e}}),s=t[n];nr.parts.length&&(n.parts.length=r.parts.length)}else{for(var a=[],i=0;ir&&this.$nextTick(function(){e.__form__[t]=Number(n.slice(0,-1))})},isSomeRowEditing:function(){var e=this.injectedData.find(function(e){return e.__editable__});return!!e&&(e.__warning__=!0,!0)},create:function(){var e=a({},this.model,{id:null}),t={};for(var r in e)t[r]={isError:!1,message:""};this.injectedData.push(a({},e,{__error__:t,__warning__:!1,__editable__:!0,__form__:a({},this.model)}))},update:function(e,t){e.__editable__=!0},destroy:function(e,t){var r=this;this.$confirm("确定要删除?","确认",{type:"warning"}).then(function(){r.remove(t),r.$emit("destroy",e,t)}).catch(function(e){})},cancelEdit:function(e,t){if(e.id){var r={},n={};for(var i in e)"__form__"!==i&&"__editable__"!==i&&"__error__"!==i&&"__warning__"!==i&&(r[i]=e[i],n[i]={isError:!1,message:""});e.__form__=r,e.__error__=n,e.__editable__=!1}else this.injectedData.splice(t,1)},validate:function(e,t){var r=this;return new Promise(function(n,i){new o.a(r.computedRules).validate(e,function(e,r){if(r)for(var i in r)t[i]={isError:!0,message:r[i][0].message};n(!r)})})},submit:function(e,t){var r=this,n=e.id?1:0,i=function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];e.__editable__=t},o=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;e.id=t,e.__form__.id=t};this.validate(e.__form__,e.__error__).then(function(t){t&&(r.commit(e),r.$emit("submit",n,e.__form__,i,o))})},remove:function(e){this.injectedData.splice(e,1)},commit:function(e){for(var t in e.__form__)e[t]=e.__form__[t]},handleExpand:function(e,t){this.$emit("expand",e,t)},handleRowClick:function(e,t,r){this.$emit("row-click",e,t,r)},handleRowDblclick:function(e,t){this.$emit("row-dblclick",e,t)}}}},function(e,t,r){"use strict";function n(e){this.rules=null,this._messages=u.messages,this.define(e)}Object.defineProperty(t,"__esModule",{value:!0});var i=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},l=arguments[2],d=e,c=s,p=l;if("function"==typeof c&&(p=c,c={}),!this.rules||0===Object.keys(this.rules).length)return void(p&&p());if(c.messages){var m=this.messages();m===u.messages&&(m=(0,u.newMessages)()),(0,a.deepMerge)(m,c.messages),c.messages=m}else c.messages=this.messages();c.error=f.error;var _=void 0,y=void 0,h={};(c.keys||Object.keys(this.rules)).forEach(function(t){_=r.rules[t],y=d[t],_.forEach(function(n){var o=n;"function"==typeof o.transform&&(d===e&&(d=i({},d)),y=d[t]=o.transform(y)),o="function"==typeof o?{validator:o}:i({},o),o.validator=r.getValidationMethod(o),o.field=t,o.fullField=o.fullField||t,o.type=r.getType(o),o.validator&&(h[t]=h[t]||[],h[t].push({rule:o,value:y,source:d,field:t}))})});var v={};(0,a.asyncMap)(h,c,function(e,t){function r(e,t){return i({},t,{fullField:l.fullField+"."+e})}function s(){var o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],s=o;if(Array.isArray(s)||(s=[s]),s.length&&(0,a.warning)("async-validator:",s),s.length&&l.message&&(s=[].concat(l.message)),s=s.map((0,a.complementError)(l)),(c.first||c.fieldFirst)&&s.length)return v[l.field]=1,t(s);if(u){if(l.required&&!e.value)return s=l.message?[].concat(l.message).map((0,a.complementError)(l)):[c.error(l,(0,a.format)(c.messages.required,l.field))],t(s);var f={};if(l.defaultField)for(var d in e.value)e.value.hasOwnProperty(d)&&(f[d]=l.defaultField);f=i({},f,e.rule.fields);for(var p in f)if(f.hasOwnProperty(p)){var m=Array.isArray(f[p])?f[p]:[f[p]];f[p]=m.map(r.bind(null,p))}var _=new n(f);_.messages(c.messages),e.rule.options&&(e.rule.options.messages=c.messages,e.rule.options.error=c.error),_.validate(e.value,e.rule.options||c,function(e){t(e&&e.length?s.concat(e):e)})}else t(s)}var l=e.rule,u=!("object"!==l.type&&"array"!==l.type||"object"!==o(l.fields)&&"object"!==o(l.defaultField));u=u&&(l.required||!l.required&&e.value),l.field=e.field,l.validator(l,e.value,s,e.source,c)},function(e){t(e)})},getType:function(e){if(void 0===e.type&&e.pattern instanceof RegExp&&(e.type="pattern"),"function"!=typeof e.validator&&e.type&&!l.default.hasOwnProperty(e.type))throw new Error((0,a.format)("Unknown rule type %s",e.type));return e.type||"string"},getValidationMethod:function(e){if("function"==typeof e.validator)return e.validator;var t=Object.keys(e),r=t.indexOf("message");return-1!==r&&t.splice(r,1),1===t.length&&"required"===t[0]?l.default.required:l.default[this.getType(e)]||!1}},n.register=function(e,t){if("function"!=typeof t)throw new Error("Cannot register a validator by type, validator is not a function");l.default[e]=t},n.messages=u.messages,t.default=n,e.exports=t.default},function(e,t,r){"use strict";e.exports={string:r(21),method:r(27),number:r(28),boolean:r(29),regexp:r(30),integer:r(31),float:r(32),array:r(33),object:r(34),enum:r(35),pattern:r(36),email:r(3),url:r(3),date:r(37),hex:r(3),required:r(38)}},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t,"string")&&!e.required)return r();o.default.required(e,t,n,s,i,"string"),(0,a.isEmptyValue)(t,"string")||(o.default.type(e,t,n,s,i),o.default.range(e,t,n,s,i),o.default.pattern(e,t,n,s,i),!0===e.whitespace&&o.default.whitespace(e,t,n,s,i))}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){(/^\s+$/.test(t)||""===t)&&n.push(o.format(i.messages.whitespace,e.fullField))}Object.defineProperty(t,"__esModule",{value:!0});var i=r(0),o=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(i);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,o){if(e.required&&void 0===t)return void(0,l.default)(e,t,r,n,o);var s=["integer","float","array","regexp","object","method","email","number","date","url","hex"],u=e.type;s.indexOf(u)>-1?f[u](t)||n.push(a.format(o.messages.types[u],e.fullField,e.type)):u&&(void 0===t?"undefined":i(t))!==e.type&&n.push(a.format(o.messages.types[u],e.fullField,e.type))}Object.defineProperty(t,"__esModule",{value:!0});var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=r(0),a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(o),s=r(8),l=function(e){return e&&e.__esModule?e:{default:e}}(s),u={email:/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,url:new RegExp("^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$","i"),hex:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i},f={integer:function(e){return f.number(e)&&parseInt(e,10)===e},float:function(e){return f.number(e)&&!f.integer(e)},array:function(e){return Array.isArray(e)},regexp:function(e){if(e instanceof RegExp)return!0;try{return!!new RegExp(e)}catch(e){return!1}},date:function(e){return"function"==typeof e.getTime&&"function"==typeof e.getMonth&&"function"==typeof e.getYear},number:function(e){return!isNaN(e)&&"number"==typeof e},object:function(e){return"object"===(void 0===e?"undefined":i(e))&&!f.array(e)},method:function(e){return"function"==typeof e},email:function(e){return"string"==typeof e&&!!e.match(u.email)},url:function(e){return"string"==typeof e&&!!e.match(u.url)},hex:function(e){return"string"==typeof e&&!!e.match(u.hex)}};t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var a="number"==typeof e.len,s="number"==typeof e.min,l="number"==typeof e.max,u=t,f=null,d="number"==typeof t,c="string"==typeof t,p=Array.isArray(t);if(d?f="number":c?f="string":p&&(f="array"),!f)return!1;(c||p)&&(u=t.length),a?u!==e.len&&n.push(o.format(i.messages[f].len,e.fullField,e.len)):s&&!l&&ue.max?n.push(o.format(i.messages[f].max,e.fullField,e.max)):s&&l&&(ue.max)&&n.push(o.format(i.messages[f].range,e.fullField,e.min,e.max))}Object.defineProperty(t,"__esModule",{value:!0});var i=r(0),o=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(i);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){e[a]=Array.isArray(e[a])?e[a]:[],-1===e[a].indexOf(t)&&n.push(o.format(i.messages[a],e.fullField,e[a].join(", ")))}Object.defineProperty(t,"__esModule",{value:!0});var i=r(0),o=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(i),a="enum";t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){e.pattern instanceof RegExp&&(e.pattern.test(t)||n.push(o.format(i.messages.pattern.mismatch,e.fullField,t,e.pattern)))}Object.defineProperty(t,"__esModule",{value:!0});var i=r(0),o=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(i);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t)&&!e.required)return r();o.default.required(e,t,n,s,i),void 0!==t&&o.default.type(e,t,n,s,i)}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t)&&!e.required)return r();o.default.required(e,t,n,s,i),void 0!==t&&(o.default.type(e,t,n,s,i),o.default.range(e,t,n,s,i))}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,o){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,i.isEmptyValue)(t)&&!e.required)return r();a.default.required(e,t,n,s,o),void 0!==t&&a.default.type(e,t,n,s,o)}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(0),o=r(1),a=function(e){return e&&e.__esModule?e:{default:e}}(o);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t)&&!e.required)return r();o.default.required(e,t,n,s,i),(0,a.isEmptyValue)(t)||o.default.type(e,t,n,s,i)}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t)&&!e.required)return r();o.default.required(e,t,n,s,i),void 0!==t&&(o.default.type(e,t,n,s,i),o.default.range(e,t,n,s,i))}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t)&&!e.required)return r();o.default.required(e,t,n,s,i),void 0!==t&&(o.default.type(e,t,n,s,i),o.default.range(e,t,n,s,i))}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t,"array")&&!e.required)return r();o.default.required(e,t,n,s,i,"array"),(0,a.isEmptyValue)(t,"array")||(o.default.type(e,t,n,s,i),o.default.range(e,t,n,s,i))}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t)&&!e.required)return r();o.default.required(e,t,n,s,i),void 0!==t&&o.default.type(e,t,n,s,i)}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var l=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t)&&!e.required)return r();o.default.required(e,t,n,l,i),t&&o.default[s](e,t,n,l,i)}r(l)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0),s="enum";t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t,"string")&&!e.required)return r();o.default.required(e,t,n,s,i),(0,a.isEmptyValue)(t,"string")||o.default.pattern(e,t,n,s,i)}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,i){var s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if((0,a.isEmptyValue)(t)&&!e.required)return r();o.default.required(e,t,n,s,i),(0,a.isEmptyValue)(t)||(o.default.type(e,t,n,s,i),t&&o.default.range(e,t.getTime(),n,s,i))}r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i=r(1),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=r(0);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(e,t,r,n,o){var s=[],l=Array.isArray(t)?"array":void 0===t?"undefined":i(t);a.default.required(e,t,n,s,o,l),r(s)}Object.defineProperty(t,"__esModule",{value:!0});var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=r(1),a=function(e){return e&&e.__esModule?e:{default:e}}(o);t.default=n,e.exports=t.default},function(e,t,r){"use strict";function n(){return{default:"Validation error on field %s",required:"%s is required",enum:"%s must be one of %s",whitespace:"%s cannot be empty",date:{format:"%s date %s is invalid for format %s",parse:"%s date could not be parsed, %s is invalid ",invalid:"%s date %s is invalid"},types:{string:"%s is not a %s",method:"%s is not a %s (function)",array:"%s is not an %s",object:"%s is not an %s",number:"%s is not a %s",date:"%s is not a %s",boolean:"%s is not a %s",integer:"%s is not an %s",float:"%s is not a %s",regexp:"%s is not a valid %s",email:"%s is not a valid %s",url:"%s is not a valid %s",hex:"%s is not a valid %s"},string:{len:"%s must be exactly %s characters",min:"%s must be at least %s characters",max:"%s cannot be longer than %s characters",range:"%s must be between %s and %s characters"},number:{len:"%s must equal %s",min:"%s cannot be less than %s",max:"%s cannot be greater than %s",range:"%s must be between %s and %s"},array:{len:"%s must be exactly %s in length",min:"%s cannot be less than %s in length",max:"%s cannot be greater than %s in length",range:"%s must be between %s and %s in length"},pattern:{mismatch:"%s value %s does not match pattern %s"},clone:function(){var e=JSON.parse(JSON.stringify(this));return e.clone=this.clone,e}}}Object.defineProperty(t,"__esModule",{value:!0}),t.newMessages=n;t.messages=n()},function(e,t,r){"use strict";var n=function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("div",{staticClass:"crud"},[e.actions.includes("create")?r("div",{staticClass:"crud__ctrl"},[e._t("action.create",[r("el-button",{attrs:{type:"primary",size:"small",icon:"el-icon-plus"},on:{click:e.create}})])],2):e._e(),e._v(" "),r("el-table",{attrs:{data:e.injectedData,stripe:"",border:"","row-style":e.rowStyle||void 0,"highlight-current-row":e.highlightCurrentRow},on:{expand:e.handleExpand,"row-click":e.handleRowClick,"row-dblclick":e.handleRowDblclick}},[e._t("expand"),e._v(" "),e._t("index"),e._v(" "),e._t("prepend"),e._v(" "),e._l(Object.keys(e.columns),function(t,n){return[t in e.fields&&e.fields[t].options&&!e.fields[t].raw?r("el-table-column",{key:n,attrs:{label:e.columns[t],"min-width":e.labelWidth,"show-overflow-tooltip":""},scopedSlots:e._u([{key:"default",fn:function(n){return[n.row.__editable__?[r("el-select",e._b({staticClass:"crud__select",class:{"is-error":n.row.__error__[t].isError},attrs:{placeholder:e.columns[t]},on:{change:function(r){e.clearErrors(n.row,t)}},model:{value:n.row.__form__[t],callback:function(r){e.$set(n.row.__form__,t,r)},expression:"scope.row.__form__[key]"}},"el-select",e.fields[t],!1),e._l(e.fields[t].options,function(t,n){return r("el-option",e._b({key:n},"el-option",t,!1))}))]:[e._v("\n "+e._s((e.fields[t].options.find(function(e){return e.value===n.row[t]})||"").label)+"\n ")]]}}])}):r("el-table-column",{key:n,attrs:{label:e.columns[t],"min-width":e.labelWidth,prop:t,"show-overflow-tooltip":""},scopedSlots:e._u([{key:"default",fn:function(n){return[n.row.__editable__?[e.fields[t].editable||void 0===e.fields[t].editable?["string"===e.fields[t].type||"text"===e.fields[t].type?r("el-input",e._b({staticClass:"crud__input",class:{"is-error":n.row.__error__[t].isError},attrs:{placeholder:e.columns[t],maxlength:e.fields[t].maxlength},on:{change:function(r){e.clearErrors(n.row,t)}},nativeOn:{keydown:function(t){if(!("button"in t)&&13!==t.keyCode)return null;e.submit(n.row)}},model:{value:n.row.__form__[t],callback:function(r){e.$set(n.row.__form__,t,r)},expression:"scope.row.__form__[key]"}},"el-input",e.fields[t],!1)):"number"===e.fields[t].type?r("el-input",e._b({staticClass:"crud__input",class:{"is-error":n.row.__error__[t].isError},attrs:{type:"number",placeholder:e.columns[t]},on:{change:function(r){e.clearErrors(n.row,t)}},nativeOn:{input:function(r){e.handleNumberInput(n.row,t,e.fields[t].maxlength)},keydown:function(t){if(!("button"in t)&&13!==t.keyCode)return null;e.submit(n.row)}},model:{value:n.row.__form__[t],callback:function(r){e.$set(n.row.__form__,t,r)},expression:"scope.row.__form__[key]"}},"el-input",e.fields[t],!1)):"date"===e.fields[t].type||"datetime"===e.fields[t].type?r("el-date-picker",e._b({staticClass:"crud__input",staticStyle:{width:"100%"},attrs:{type:e.fields[t].type,placeholder:e.columns[t]},on:{change:function(r){e.clearErrors(n.row,t)}},model:{value:n.row.__form__[t],callback:function(r){e.$set(n.row.__form__,t,r)},expression:"scope.row.__form__[key]"}},"el-date-picker",e.fields[t],!1)):"boolean"===e.fields[t].type?r("el-radio-group",e._b({attrs:{size:"small"},on:{change:function(r){e.clearErrors(n.row,t)}},model:{value:n.row.__form__[t],callback:function(r){e.$set(n.row.__form__,t,r)},expression:"scope.row.__form__[key]"}},"el-radio-group",e.fields[t],!1),[r("el-radio-button",{attrs:{label:"是"}}),e._v(" "),r("el-radio-button",{attrs:{label:"否"}})],1):e._e()]:[e.fields[t].formatter?[e._v("\n "+e._s(e.fields[t].formatter(n.row[t],n.row))+"\n ")]:e._e()]]:[e.fields[t].formatter&&!1!==e.fields[t].editable?[e._v("\n "+e._s(e.fields[t].formatter(n.row[t],n.row))+"\n ")]:[e._v("\n "+e._s(n.row[t])+"\n ")]]]}}])})]}),e._v(" "),e._t("default"),e._v(" "),e.actions.includes("update")||e.actions.includes("destroy")?r("el-table-column",{attrs:{label:"操作",width:"150",align:"center"},scopedSlots:e._u([{key:"default",fn:function(t){return[t.row.__editable__?[r("div",{class:{shake:t.row.__warning__},on:{animationend:function(e){t.row.__warning__=!1}}},[r("el-button",{attrs:{type:"success",size:"small",icon:"el-icon-check"},on:{click:function(r){r.stopPropagation(),e.submit(t.row)}}}),e._v(" "),r("el-button",{attrs:{type:"danger",size:"small",icon:"el-icon-close"},on:{click:function(r){r.stopPropagation(),e.cancelEdit(t.row,t.$index)}}})],1)]:[e.actions.includes("update")?r("el-button",{attrs:{type:"warning",size:"small",icon:"el-icon-edit"},on:{click:function(r){r.stopPropagation(),e.update(t.row,t.$index)}}}):e._e(),e._v(" "),e.actions.includes("destroy")?r("el-button",{attrs:{type:"danger",size:"small",icon:"el-icon-delete"},on:{click:function(r){r.stopPropagation(),e.destroy(t.row,t.$index)}}}):e._e()]]}}])}):e._e()],2)],1)},i=[],o={render:n,staticRenderFns:i};t.a=o},function(e,t,r){"use strict";var n=r(4),i=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:"",r=arguments[2],n={create:"新增",update:"修改",destroy:"删除"},o=n[t]||t||"操作";1===e.code?(i.Message.success(o+"成功!"),r(e)):i.Message.error(o+"失败!"+e.msg)}t.a=n;var i=r(43);r.n(i)},function(t,r){t.exports=e}])}); -------------------------------------------------------------------------------- /dist/element-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wisetc/vue-element-crud/ab621cd065ac62dc9c3c100cc4e2d2ed6abfea8d/dist/element-icons.ttf -------------------------------------------------------------------------------- /dist/element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wisetc/vue-element-crud/ab621cd065ac62dc9c3c100cc4e2d2ed6abfea8d/dist/element-icons.woff -------------------------------------------------------------------------------- /example/info - 01/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 103 | -------------------------------------------------------------------------------- /example/info - 01/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | import 'element-ui/lib/theme-chalk/index.css' 5 | import ElementUI from 'element-ui' 6 | import CRUD from '../../dist/crud.common' 7 | 8 | Vue.use(ElementUI) 9 | Vue.use(CRUD) 10 | 11 | new Vue({ 12 | el: '#app', 13 | render: h => h(App) 14 | }) 15 | -------------------------------------------------------------------------------- /example/info - 01/xhr/index.js: -------------------------------------------------------------------------------- 1 | let initData = [ 2 | { id: 1, name: '大暗扣', phone: 1858849, mail: 'zhi@xxx.com', site: 'http://www.example.com' } 3 | ] 4 | 5 | export const Customer = { 6 | list: () => new Promise((resolve, reject) => { 7 | resolve({ 8 | data: { 9 | data: { 10 | data: initData 11 | }, 12 | code: 1 13 | }, 14 | status: 200 15 | }) 16 | }), 17 | create: params => new Promise((resolve, reject) => { 18 | let data = { ...params, id: initData[initData.length - 1].id + 1 } 19 | initData = initData.concat(data) 20 | resolve({ 21 | data: { 22 | data: { 23 | data: data 24 | }, 25 | code: 1 26 | }, 27 | status: 200 28 | }) 29 | }), 30 | retrieve: () => {}, 31 | update: params => new Promise((resolve, reject) => { 32 | let index = initData.findIndex(item => item.id === params.id) 33 | for (let k in initData[index]) { 34 | initData[index][k] = params[k] 35 | } 36 | resolve({ 37 | data: { 38 | data: { 39 | data: params 40 | }, 41 | code: 1 42 | } 43 | }) 44 | }), 45 | destroy: id => new Promise((resolve, reject) => { 46 | let index = initData.findIndex(item => item.id === id) 47 | initData.splice(index, 1) 48 | resolve({ 49 | data: { 50 | data: { 51 | data: initData 52 | }, 53 | code: 1 54 | }, 55 | status: 200 56 | }) 57 | }) 58 | } 59 | -------------------------------------------------------------------------------- /example/info inline - 02/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 124 | -------------------------------------------------------------------------------- /example/info inline - 02/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | import "element-ui/lib/theme-chalk/index.css" 5 | import ElementUI from 'element-ui' 6 | import CRUD from '../../dist/crud.common' 7 | 8 | Vue.use(ElementUI) 9 | Vue.use(CRUD) 10 | 11 | new Vue({ 12 | el: '#app', 13 | render: h => h(App) 14 | }) 15 | -------------------------------------------------------------------------------- /example/info inline - 02/xhr/index.js: -------------------------------------------------------------------------------- 1 | let initData = [ 2 | { id: 1, name: '大暗扣', phone: 18588497777, mail: 'zhi@xxx.com', site: 'http://www.example.com', birth: '1991-01-01', married: false, age: 27 } 3 | ] 4 | 5 | export const Customer = { 6 | list: () => new Promise((resolve, reject) => { 7 | resolve({ 8 | data: { 9 | data: { 10 | data: initData 11 | }, 12 | code: 1 13 | }, 14 | status: 200 15 | }) 16 | }), 17 | create: params => new Promise((resolve, reject) => { 18 | let data = { ...params, id: initData[initData.length - 1].id + 1 } 19 | initData = initData.concat(data) 20 | resolve({ 21 | data: { 22 | data: { 23 | data: data 24 | }, 25 | code: 1 26 | }, 27 | status: 200 28 | }) 29 | }), 30 | retrieve: () => {}, 31 | update: params => new Promise((resolve, reject) => { 32 | let index = initData.findIndex(item => item.id === params.id) 33 | for (let k in initData[index]) { 34 | initData[index][k] = params[k] 35 | } 36 | resolve({ 37 | data: { 38 | data: { 39 | data: params 40 | }, 41 | code: 1 42 | } 43 | }) 44 | }), 45 | destroy: id => new Promise((resolve, reject) => { 46 | let index = initData.findIndex(item => item.id === id) 47 | initData.splice(index, 1) 48 | resolve({ 49 | data: { 50 | data: { 51 | data: initData 52 | }, 53 | code: 1 54 | }, 55 | status: 200 56 | }) 57 | }) 58 | } 59 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-element-crud demo 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-element-crud", 3 | "version": "3.1.0", 4 | "description": "A CRUD component for vue projects to create, retrieve, update and destroy models.", 5 | "main": "dist/crud.common.js", 6 | "directories": { 7 | "lib": "dist", 8 | "example": "example" 9 | }, 10 | "scripts": { 11 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", 12 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules", 13 | "build:watch": "cross-env NODE_ENV=production webpack --progress --hide-modules -w" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/wisetc/vue-element-crud.git" 18 | }, 19 | "keywords": [ 20 | "vue-crud", 21 | "vue-element-crud", 22 | "element-crud" 23 | ], 24 | "author": { 25 | "name": "Mark Wang", 26 | "email": "zhi@uqugu.com" 27 | }, 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/wisetc/vue-element-crud/issues" 31 | }, 32 | "homepage": "https://github.com/wisetc/vue-element-crud#readme", 33 | "dependencies": { 34 | "element-ui": "^2.2.0", 35 | "vue": "2.5.9" 36 | }, 37 | "devDependencies": { 38 | "babel-core": "^6.26.0", 39 | "babel-loader": "^7.1.2", 40 | "babel-preset-env": "^1.6.0", 41 | "babel-preset-stage-2": "^6.24.1", 42 | "cross-env": "^5.0.5", 43 | "css-loader": "^0.28.7", 44 | "file-loader": "^1.1.4", 45 | "style-loader": "^0.19.0", 46 | "vue-loader": "^13.0.5", 47 | "vue-template-compiler": "2.5.9", 48 | "webpack": "^3.6.0", 49 | "webpack-dev-server": "^2.9.1" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Crud.vue: -------------------------------------------------------------------------------- 1 | 66 | 67 | 215 | 216 | 233 | -------------------------------------------------------------------------------- /src/CrudInline.vue: -------------------------------------------------------------------------------- 1 | 118 | 119 | 333 | 334 | 369 | -------------------------------------------------------------------------------- /src/fieldType.js: -------------------------------------------------------------------------------- 1 | const fieldTypes = ['string', 'text', 'boolean', 'integer', 'float', 'date', 'datetime', 'objectid'] 2 | 3 | export default fieldTypes.reduce((x, y, i) => ( 4 | {...x, [y]: y} 5 | ), {}) 6 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import CRUD from './Crud.vue' 2 | import CRUDInline from './CrudInline.vue' 3 | import Simple from './mixins/Simple' 4 | import fields from './fieldType' 5 | import report from './report' 6 | 7 | const install = (Vue, opt) => { 8 | Vue.component('crud', CRUD) 9 | Vue.component('crud-inline', CRUDInline) 10 | Vue.prototype.$report = report 11 | } 12 | 13 | if (typeof window !== 'undefined' && window.Vue) { 14 | install(window.Vue); 15 | } 16 | 17 | export default { 18 | install 19 | } 20 | 21 | export { 22 | fields, 23 | CRUD, 24 | Simple 25 | } 26 | -------------------------------------------------------------------------------- /src/mixins/Simple.js: -------------------------------------------------------------------------------- 1 | import CRUD from '../Crud.vue' 2 | 3 | export default { 4 | components: { crud: CRUD }, 5 | data() { 6 | return { 7 | data: [], 8 | 9 | form: {}, 10 | 11 | fields: { 12 | // user implement 13 | } 14 | } 15 | }, 16 | 17 | computed: { 18 | model() { 19 | let model = {} 20 | let fields = this.fields 21 | for (let k in fields) { 22 | model[k] = null 23 | } 24 | return model 25 | }, 26 | 27 | rules() { 28 | let rules = {} 29 | let fields = this.fields 30 | for (let k in fields) { 31 | if (fields[k].rules) { 32 | rules[k] = fields[k].rules.concat({ pattern: /^\S.*?$/, message: '不允许以空格开头' }) 33 | } 34 | } 35 | return rules 36 | } 37 | }, 38 | 39 | methods: { 40 | loadData() {}, // user implement 41 | 42 | handleCreate() { 43 | this.form = { ...this.model } 44 | }, 45 | 46 | handleUpdate(row, index) { 47 | this.form = { ...row } 48 | }, 49 | 50 | handleDestroy(row, index) {}, // user implement 51 | 52 | handleSubmit(status, closeDialog) { 53 | const submitSuccess = (data) => { 54 | this.loadData() 55 | closeDialog() 56 | } 57 | 58 | if (status === 0) { 59 | 60 | } else { 61 | 62 | } 63 | }, // user implement 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/report.js: -------------------------------------------------------------------------------- 1 | import { Message } from 'element-ui' 2 | 3 | export default function report (data, type='', callback) { 4 | let map = { 5 | create: '新增', 6 | update: '修改', 7 | destroy: '删除' 8 | } 9 | let msg = map[type] || type || '操作' 10 | 11 | if (data.code === 1) { 12 | Message.success(msg + '成功!') 13 | callback(data) 14 | } else { 15 | Message.error(msg + '失败!' + data.msg) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | // entry: './example/info - 01/main.js', 6 | entry: './example/info inline - 02/main.js', 7 | output: { 8 | path: path.resolve(__dirname, './dist'), 9 | publicPath: '/dist/', 10 | filename: 'build.js' 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.css$/, 16 | loader: 'style-loader!css-loader' 17 | }, 18 | { 19 | test: /\.vue$/, 20 | loader: 'vue-loader', 21 | options: { 22 | loaders: { 23 | } 24 | // other vue-loader options go here 25 | } 26 | }, 27 | { 28 | test: /\.js$/, 29 | loader: 'babel-loader', 30 | exclude: /node_modules/ 31 | }, 32 | { 33 | test: /\.(png|jpg|gif|svg|ttf|woff)$/, 34 | loader: 'file-loader', 35 | options: { 36 | name: '[name].[ext]?[hash]' 37 | } 38 | } 39 | ] 40 | }, 41 | resolve: { 42 | alias: { 43 | 'vue$': 'vue/dist/vue.esm.js' 44 | } 45 | }, 46 | devServer: { 47 | historyApiFallback: true, 48 | noInfo: true, 49 | overlay: true 50 | }, 51 | performance: { 52 | hints: false 53 | }, 54 | devtool: '#eval-source-map' 55 | } 56 | 57 | if (process.env.NODE_ENV === 'production') { 58 | module.exports.entry = './src/index.js' 59 | module.exports.output = { 60 | path: path.resolve(__dirname, './dist'), 61 | publicPath: '/dist/', 62 | filename: 'crud.common.js', 63 | library: 'CRUD', 64 | libraryTarget: 'umd' 65 | } 66 | module.exports.externals = ['element-ui'] 67 | module.exports.devtool = false 68 | // http://vue-loader.vuejs.org/en/workflow/production.html 69 | module.exports.plugins = (module.exports.plugins || []).concat([ 70 | new webpack.DefinePlugin({ 71 | 'process.env': { 72 | NODE_ENV: '"production"' 73 | } 74 | }), 75 | new webpack.optimize.UglifyJsPlugin({ 76 | sourceMap: true, 77 | compress: { 78 | warnings: false 79 | } 80 | }), 81 | new webpack.LoaderOptionsPlugin({ 82 | minimize: true 83 | }) 84 | ]) 85 | } 86 | --------------------------------------------------------------------------------