├── .editorconfig
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── babel.config.js
├── example
├── App.vue
├── CustomRate.vue
├── CustomSlider.vue
└── main.js
├── package-lock.json
├── package.json
├── public
├── example.gif
├── favicon.ico
├── img
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ └── 5.png
└── index.html
├── src
├── EleEditable.vue
├── EleEditableMixin.js
├── EleEditableWrapper.vue
├── components
│ ├── EleCommonTime.vue
│ ├── EleEditableCheckbox.vue
│ ├── EleEditableColor.vue
│ ├── EleEditableDate.vue
│ ├── EleEditableDateText.vue
│ ├── EleEditableDatetime.vue
│ ├── EleEditableDatetimeText.vue
│ ├── EleEditableImage.vue
│ ├── EleEditableInput.vue
│ ├── EleEditableNumber.vue
│ ├── EleEditableRadio.vue
│ ├── EleEditableSelect.vue
│ ├── EleEditableStatus.vue
│ ├── EleEditableSwitch.vue
│ ├── EleEditableText.vue
│ ├── EleEditableTextarea.vue
│ ├── EleEditableTime.vue
│ ├── EleEditableTimeText.vue
│ ├── EleEditableUploadImage.vue
│ └── EleEditableUrl.vue
├── index.js
└── wrapper
│ ├── EleEditableWrapperDisplay.vue
│ └── EleEditableWrapperForm.vue
└── vue.config.js
/.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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | tests
3 | docs
4 | documentation
5 | public
6 | vue.config.js
7 | coverage
8 | example
9 | jest.config.js
10 | .eslintrc.js
11 | cypress.json
12 | .browserslistrc
13 | postcss.config.js
14 | babel.config.js
15 | .editorconfig
16 | .cypress.json
17 | .vscode
18 | .env.docs
19 | dist/demo.html
20 | .env.dev-doc
21 | .env.dev-example
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 二当家的
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-ele-editable | 高效、简单、强大的 element-ui 行内编辑组件
2 |
3 | [](https://opensource.org/licenses/mit-license.php)
4 | [](https://www.npmjs.com/package/vue-ele-editable)
5 | [](https://npmcharts.com/compare/vue-ele-editable?minimal=true)
6 |
7 | ## 介绍
8 |
9 | vue-ele-editable 是一个高效、简单、强大的 element-ui 行内编辑组件, 引用组件后, 仅通过数据就可以完成行内编辑功能, 具体特点如下:
10 |
11 | - 支持多种内置组件: input、select、radio、checkbox、textarea、date、time、datetime、text、url、status、switch、image、upload-image、time-text、date-text、datetime-text、color、number
12 | - 支持 Popover 和 Inline 两种模式
13 | - 支持数据校检、自定义属性、自定义显示数据、自定义发送数据
14 | - 足够简单, 仅需要 1 行 html 代码和数据即可
15 |
16 | > 为了帮助您更好的了解和使用, star 数超过 100 的话, 有视频源码讲解, 希望能给个 star😘😘😘
17 |
18 | ## 效果图
19 |
20 | [](https://codepen.io/dream2023/pen/dBNNbP)
21 |
22 | ## 在线示例
23 |
24 | [https://codepen.io/dream2023/pen/dBNNbP](https://codepen.io/dream2023/pen/dBNNbP)
25 |
26 | ## 安装
27 |
28 | ```bash
29 | npm install vue-ele-editable --save
30 | ```
31 |
32 | ## 使用
33 |
34 | ```js
35 | import EleEditable from 'vue-ele-editable'
36 | Vue.use(EleEditable)
37 |
38 | // 在引入 EleEditable 时,可以传入一个全局配置对象
39 | // key 是组件名, value 是组件的属性, 例如:
40 | Vue.use(EleEditable, {
41 | // 所有 image 类型的组件都会有 lazy: true 的属性
42 | image: {
43 | lazy: true
44 | },
45 | // 所有的 number 类型的组件都会有 step: 10 的属性
46 | number: {
47 | step: 10
48 | },
49 | ...
50 | })
51 | ```
52 |
53 | ## Props
54 |
55 | ### 参数总览
56 |
57 | ```js
58 | props: {
59 | // 类型
60 | type: {
61 | type: String,
62 | default: 'text'
63 | },
64 | // 字段
65 | field: {
66 | type: String,
67 | required: true
68 | },
69 | // 是否为行内
70 | inline: {
71 | type: Boolean,
72 | default: false
73 | },
74 | // 标题
75 | title: String,
76 | // 字段值
77 | value: [String, Number, Boolean, Array, Date],
78 | // 默认值
79 | defaultValue: {
80 | type: [String, Number, Boolean, Array, Date],
81 | default: null
82 | },
83 | // 自定义组件是否需要包裹
84 | isNoWrapper: {
85 | type: Boolean,
86 | default: false
87 | },
88 | // 选项
89 | options: {
90 | type: Array,
91 | default () {
92 | return []
93 | }
94 | },
95 | // 请求地址
96 | requestFn: Function,
97 | // 校检规则
98 | rules: [Array, Object],
99 | // 其他附带数据
100 | customData: Object,
101 | // 自定义属性
102 | customAttrs: Object,
103 | // 格式化显示数据
104 | displayFormatter: Function,
105 | // 对请求数据格式化
106 | valueFormatter: Function,
107 | // 值空时显示的文本
108 | emptyText: {
109 | type: String,
110 | default: '空'
111 | }
112 | }
113 | ```
114 |
115 | ### 参数讲解
116 |
117 | #### type:
118 |
119 | `type` 用于指定渲染组件, 目前支持的内置组件有:
120 |
121 | | 类型 | 含义 | 属性参考 |
122 | | ------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------- |
123 | | text | 静态文本 | |
124 | | image | 单个图片/多张图片 | [vue-ele-gallery](https://github.com/dream2023/vue-ele-gallery) |
125 | | upload-image | 上传图片 | [vue-ele-upload-image](https://github.com/dream2023/vue-ele-upload-image) |
126 | | input | 可编辑的单行文本 | [element-ui input](https://element.eleme.cn/#/zh-CN/component/input) |
127 | | textarea | 可编辑的多行文本 | [element-ui input](https://element.eleme.cn/#/zh-CN/component/input) |
128 | | select | 下拉框 | [element-ui select](https://element.eleme.cn/#/zh-CN/component/select) |
129 | | number | 可编辑数字 | [element-ui input-number](https://element.eleme.cn/#/zh-CN/component/input-number) |
130 | | radio | 单选 | [element-ui radio](https://element.eleme.cn/#/zh-CN/component/radio) |
131 | | checkbox | 多选 | [element-ui checkbox](https://element.eleme.cn/#/zh-CN/component/checkbox) |
132 | | datetime | 可编辑的日期时间 (可接受时间戳, 字符串, Date 类型值) | [element-ui datetime-picker](https://element.eleme.cn/#/zh-CN/component/datetime-picker) |
133 | | datetime-text | 不可编辑的日期时间 (接受值同上) | |
134 | | date | 可编辑的日期 (接受值同上) | [element-ui date-picker](https://element.eleme.cn/#/zh-CN/component/date-picker) |
135 | | date-text | 不可编辑的日期 (接受值同上) | |
136 | | time | 可编辑的时间 (接受值同上) | [element-ui time-picker](https://element.eleme.cn/#/zh-CN/component/time-picker) |
137 | | time-text | 不可编辑的时间 (接受值同上) | |
138 | | status | 状态 | [element-ui tag](https://element.eleme.cn/#/zh-CN/component/tag) |
139 | | switch | 开关 | [element-ui switch](https://element.eleme.cn/#/zh-CN/component/switch) |
140 | | url | 链接 | |
141 | | color | 颜色 | [element-ui color-picker](https://element.eleme.cn/#/zh-CN/component/color-picker) |
142 |
143 | 当`type`不是以上任何一个类型时, 就会按照传递的名字渲染, 可以进行自定义扩展组件, 具体参考 [自定义扩展示例 rate](./example/CustomRate.vue), [自定义扩展示例 slider](./example/CustomSlider.vue), 具体表现形式, 请看[在线示例](https://codepen.io/dream2023/pen/dBNNbP)
144 |
145 | ### isNoWrapper:
146 |
147 | `isNoWrapper`用于自定义组件是否需要包裹, 举例, input 是包裹组件, switch 就是不包裹组件, 内置组件的包裹与否无法改变, 只能改变自定义组件, 例如上面的 `rate` 组件就是不包裹, `slider`组件就是包裹组件
148 |
149 | ### customAttrs:
150 |
151 | `customAttrs` 自定义组件属性, 例如将 input 变为密码框:
152 |
153 | ```js
154 | {
155 | type: 'input',
156 | // 属性参考 element-ui input组件
157 | customAttrs: {
158 | 'show-password': true
159 | }
160 | }
161 | ```
162 |
163 | ### field:
164 |
165 | `field` 用于发送请求, 作为数据的 `key`, 例如:
166 |
167 | ```js
168 | {
169 | value: 'zhang'
170 | field: 'name'
171 | }
172 |
173 | // 最终发送的数据为:
174 | {
175 | name: 'zhang'
176 | }
177 | ```
178 |
179 | ### inline:
180 |
181 | `inline` 用于指定是采用 `popover` 还是 `inline` 的模式, 默认为 `popover`
182 |
183 | ### title:
184 |
185 | `title` 用于弹窗的标题
186 |
187 | ### value:
188 |
189 | `value` 值, 可用 `v-model` 绑定
190 |
191 | ### defaultValue:
192 |
193 | `defaultValue` 当 `value` 不存在时, 代替 `value`, 例如:
194 |
195 | ```js
196 | {
197 | value: '',
198 | field: 'name',
199 | defaultValue: '匿名'
200 | }
201 |
202 | // 最终显示到屏幕上为: 匿名
203 | ```
204 |
205 | ### displayFormatter:
206 |
207 | `displayFormatter` 用于对值显示的进一步处理, 例如:
208 |
209 | ```js
210 | // 伪代码
211 | {
212 | value: 10,
213 | displayFormatter: function (value) {
214 | return `${value} 岁`
215 | }
216 | }
217 |
218 | // 最终显示到屏幕上为: 10 岁
219 | ```
220 |
221 | ### emptyText:
222 |
223 | `emptyText` 用于当无数据时, 显示的字符串, 例如:
224 |
225 | ```js
226 | {
227 | field: 'mobile',
228 | // 当 value, defaultValue 和 displayFormatter都返回空时, 才起作用
229 | value: '',
230 | defaultValue: '',
231 | displayFormatter: null,
232 | emptyText: '无手机可用'
233 | }
234 |
235 | // 最终显示到屏幕上为: 无手机可用
236 | ```
237 |
238 | ### options:
239 |
240 | `options` 用于 checkbox、radio、select、status 组件的选项, 支持对象数组和字符串数组:
241 |
242 | ```js
243 | // 对象数组形式 (text 用于展示, 实际值是 value)
244 | options: [{ text: '男', value: 'male' }, { text: '女', value: 'female' }]
245 |
246 | // 字符串数组 (相当于 [{ text: '男', value: '男' }, { text: '女', value: '女' }])
247 | options: ['男', '女']
248 | ```
249 |
250 | ### requestFn:
251 |
252 | `requestFn` 请求函数, 此函数无论如何最终要返回一个 `Promise` 示例, 用于判断请求的状态和结果
253 |
254 | 有两种情况, 一种是你需要对原请求的响应结果进行处理, 可以套一层 Promise:
255 |
256 | ```js
257 | // 伪代码
258 | async function requestFn(data) {
259 | return new Promise((resolve, reject) => {
260 | try {
261 | const res = await axios.post('/post', data)
262 | // 对res做各种处理
263 | ...
264 | resolve()
265 | } catch(e) {
266 | reject(e)
267 | }
268 | })
269 | }
270 | ```
271 |
272 | 另一个种是不需要处理, 可以直接返回一个`Promise`对象
273 |
274 | ```js
275 | async function requestFn(data) {
276 | return axios.post('/post', data)
277 | }
278 | ```
279 |
280 | ### rules:
281 |
282 | `rules` 用于校检, 校检规则同 element-ui 的 form 一样, 都是使用的 [async-validator](https://github.com/yiminghe/async-validator), 支持数组和对象两种形式, 例如:
283 |
284 | ```js
285 | // 对象
286 | rules: {
287 | required: true,
288 | message: '名称不能为空'
289 | }
290 |
291 | // 数组
292 | rules: [
293 | { type: 'number', message: '年龄必须填写数字' },
294 | { required: true, message: '年龄必填填写' }
295 | ]
296 | ```
297 |
298 | ### customData:
299 |
300 | `customData` 用于携带额外数据, 例如:
301 |
302 | ```js
303 | // 伪代码
304 |
305 | // props的值
306 | {
307 | field: 'name',
308 | value: 'zhangchaojie',
309 | customData: {
310 | id: 10,
311 | status: 1
312 | }
313 | }
314 |
315 | // 最终发送的数据为:
316 | {
317 | name: 'zhangchaojie',
318 | id: 10,
319 | status: 1
320 | }
321 | ```
322 |
323 | ### valueFormatter:
324 |
325 | `valueFormatter` 用于对请求数据的进一步处理, 例如:
326 |
327 | ```js
328 | // 伪代码
329 |
330 | // props 值
331 | field: 'age',
332 | value: 10,
333 | customData: { id: 1 },
334 | valueFormatter: function (value) {
335 | return value + 1
336 | }
337 |
338 | // 最终发送的值为:
339 | {
340 | age: 11,
341 | id: 1
342 | }
343 | ```
344 |
345 | ## 参考链接
346 |
347 | - [x-editable](http://vitalets.github.io/x-editable)
348 | - [element-ui](http://element-cn.eleme.io)
349 | - [dolphinphp](https://www.kancloud.cn/ming5112/dolphinphp/256299)
350 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/example/App.vue:
--------------------------------------------------------------------------------
1 |
2 | vue-ele-editable
4 | 类型演示:
5 | 案例:
58 |