├── babel.config.js
├── public
├── example.gif
├── favicon.ico
├── img
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ └── 5.png
└── index.html
├── .editorconfig
├── vue.config.js
├── src
├── components
│ ├── EleEditableText.vue
│ ├── EleEditableColor.vue
│ ├── EleEditableNumber.vue
│ ├── EleEditableInput.vue
│ ├── EleEditableTextarea.vue
│ ├── EleEditableUrl.vue
│ ├── EleEditableRadio.vue
│ ├── EleEditableTimeText.vue
│ ├── EleEditableCheckbox.vue
│ ├── EleEditableDatetimeText.vue
│ ├── EleEditableSelect.vue
│ ├── EleEditableImage.vue
│ ├── EleCommonTime.vue
│ ├── EleEditableDate.vue
│ ├── EleEditableDateText.vue
│ ├── EleEditableDatetime.vue
│ ├── EleEditableUploadImage.vue
│ ├── EleEditableStatus.vue
│ ├── EleEditableTime.vue
│ └── EleEditableSwitch.vue
├── index.js
├── wrapper
│ ├── EleEditableWrapperForm.vue
│ └── EleEditableWrapperDisplay.vue
├── EleEditableMixin.js
├── EleEditableWrapper.vue
└── EleEditable.vue
├── .gitignore
├── .npmignore
├── example
├── CustomSlider.vue
├── main.js
├── CustomRate.vue
└── App.vue
├── LICENSE
├── package.json
└── README.md
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/public/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/vue-ele-editable/HEAD/public/example.gif
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/vue-ele-editable/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/img/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/vue-ele-editable/HEAD/public/img/1.png
--------------------------------------------------------------------------------
/public/img/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/vue-ele-editable/HEAD/public/img/2.png
--------------------------------------------------------------------------------
/public/img/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/vue-ele-editable/HEAD/public/img/3.png
--------------------------------------------------------------------------------
/public/img/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/vue-ele-editable/HEAD/public/img/4.png
--------------------------------------------------------------------------------
/public/img/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/vue-ele-editable/HEAD/public/img/5.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 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | css: { extract: false },
3 | configureWebpack: {
4 | entry: './example/main.js',
5 | output: {
6 | libraryExport: 'default'
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/EleEditableText.vue:
--------------------------------------------------------------------------------
1 |
2 | {{displayValue}}
3 |
4 |
5 |
13 |
--------------------------------------------------------------------------------
/.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
--------------------------------------------------------------------------------
/src/components/EleEditableColor.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
18 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import EleEditable from './EleEditable'
2 |
3 | const Plugin = {}
4 |
5 | Plugin.install = function (Vue, params = {}) {
6 | Vue.prototype.$EleEditableParams = params
7 | Vue.component(EleEditable.name, EleEditable)
8 | }
9 |
10 | if (typeof window !== 'undefined' && window.Vue) {
11 | Plugin.install(window.Vue)
12 | }
13 |
14 | export { EleEditable }
15 | export default Plugin
16 |
--------------------------------------------------------------------------------
/src/components/EleEditableNumber.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
19 |
--------------------------------------------------------------------------------
/src/components/EleEditableInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
19 |
--------------------------------------------------------------------------------
/src/components/EleEditableTextarea.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
21 |
--------------------------------------------------------------------------------
/src/components/EleEditableUrl.vue:
--------------------------------------------------------------------------------
1 |
2 | {{displayValue}}
7 |
8 |
9 |
24 |
--------------------------------------------------------------------------------
/example/CustomSlider.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
21 |
--------------------------------------------------------------------------------
/src/components/EleEditableRadio.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 | {{item.text}}
13 |
14 |
15 |
16 |
24 |
--------------------------------------------------------------------------------
/src/components/EleEditableTimeText.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
27 |
--------------------------------------------------------------------------------
/src/components/EleEditableCheckbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 | {{item.text}}
13 |
14 |
15 |
16 |
24 |
--------------------------------------------------------------------------------
/src/components/EleEditableDatetimeText.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
27 |
--------------------------------------------------------------------------------
/example/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import EleEditable from '../src/index'
4 | import ElementUI from 'element-ui'
5 | import 'element-ui/lib/theme-chalk/index.css'
6 | import CustomRate from './CustomRate'
7 | import CustomSlider from './CustomSlider'
8 | Vue.component(CustomRate.name, CustomRate)
9 | Vue.component(CustomSlider.name, CustomSlider)
10 |
11 | Vue.use(ElementUI)
12 | Vue.use(EleEditable, {
13 | image: {
14 | lazy: true
15 | },
16 | number: {
17 | step: 10
18 | }
19 | })
20 | Vue.config.productionTip = false
21 |
22 | new Vue({
23 | render: h => h(App)
24 | }).$mount('#app')
25 |
--------------------------------------------------------------------------------
/src/components/EleEditableSelect.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
16 |
17 |
18 |
19 |
27 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | vue-ele-editable
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/components/EleEditableImage.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
30 |
--------------------------------------------------------------------------------
/example/CustomRate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
27 |
--------------------------------------------------------------------------------
/src/components/EleCommonTime.vue:
--------------------------------------------------------------------------------
1 |
2 | {{displayValue}}
3 |
4 |
5 |
30 |
--------------------------------------------------------------------------------
/src/components/EleEditableDate.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
32 |
--------------------------------------------------------------------------------
/src/components/EleEditableDateText.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
33 |
--------------------------------------------------------------------------------
/src/components/EleEditableDatetime.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
34 |
--------------------------------------------------------------------------------
/src/components/EleEditableUploadImage.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
24 |
25 |
34 |
--------------------------------------------------------------------------------
/src/components/EleEditableStatus.vue:
--------------------------------------------------------------------------------
1 |
2 | {{displayValue}}
7 |
8 |
9 |
32 |
--------------------------------------------------------------------------------
/src/components/EleEditableTime.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 |
18 |
38 |
--------------------------------------------------------------------------------
/src/components/EleEditableSwitch.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
36 |
--------------------------------------------------------------------------------
/src/wrapper/EleEditableWrapperForm.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
46 |
--------------------------------------------------------------------------------
/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.
--------------------------------------------------------------------------------
/src/wrapper/EleEditableWrapperDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | {{emptyText}}
8 |
9 |
10 |
11 |
15 |
16 | {{displayValue}}
17 |
18 |
19 |
20 |
21 |
62 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-ele-editable",
3 | "description": "高效、简单、强大的 element-ui 行内编辑组件",
4 | "version": "1.0.3",
5 | "private": false,
6 | "license": "MIT",
7 | "scripts": {
8 | "serve": "vue-cli-service serve",
9 | "build:lib": "vue build -t lib --name vue-ele-editable -d ./dist/ ./src/index.js",
10 | "build": "npm run lint & npm run build:lib",
11 | "lint": "vue-cli-service lint"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "https://github.com/dream2023/vue-ele-editable"
16 | },
17 | "main": "dist/vue-ele-editable.umd.min.js",
18 | "homepage": "https://github.com/dream2023/vue-ele-editable",
19 | "keywords": [
20 | "vue-ele-editable",
21 | "editable",
22 | "inline edit",
23 | "edit cell",
24 | "editable table",
25 | "element table",
26 | "el-editable",
27 | "vue editable"
28 | ],
29 | "dependencies": {
30 | "dayjs": "^1.8.14",
31 | "vue-ele-gallery": "^2.1.3",
32 | "vue-ele-upload-image": "^2.0.4"
33 | },
34 | "devDependencies": {
35 | "@vue/cli-plugin-babel": "^3.8.0",
36 | "@vue/cli-plugin-eslint": "^3.8.0",
37 | "@vue/cli-service": "^3.8.0",
38 | "@vue/eslint-config-standard": "^4.0.0",
39 | "babel-eslint": "^10.0.1",
40 | "core-js": "^2.6.5",
41 | "element-ui": "^2.9.1",
42 | "eslint": "^5.16.0",
43 | "eslint-plugin-vue": "^5.0.0",
44 | "lint-staged": "^8.1.5",
45 | "vue": "^2.6.10",
46 | "vue-template-compiler": "^2.6.10"
47 | },
48 | "eslintConfig": {
49 | "root": true,
50 | "env": {
51 | "node": true
52 | },
53 | "extends": [
54 | "plugin:vue/essential",
55 | "@vue/standard"
56 | ],
57 | "rules": {},
58 | "parserOptions": {
59 | "parser": "babel-eslint"
60 | }
61 | },
62 | "postcss": {
63 | "plugins": {
64 | "autoprefixer": {}
65 | }
66 | },
67 | "browserslist": [
68 | "> 1%",
69 | "last 2 versions"
70 | ],
71 | "gitHooks": {
72 | "pre-commit": "lint-staged"
73 | },
74 | "lint-staged": {
75 | "src/*.{js,vue}": [
76 | "vue-cli-service lint",
77 | "git add"
78 | ]
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/EleEditableMixin.js:
--------------------------------------------------------------------------------
1 | import dayjs from 'dayjs'
2 |
3 | export default {
4 | // 不继承父组件隐式绑定的属性
5 | inheritAttrs: false,
6 | props: {
7 | // 类型
8 | type: {
9 | type: String,
10 | required: true
11 | },
12 | // 用于还原失败后newValue的值
13 | isError: Boolean,
14 | // 选项 (select, checkbox, radio)
15 | options: Array,
16 | // 弹窗标题
17 | title: String,
18 | // 自定义属性
19 | customAttrs: Object,
20 | // 原始值
21 | value: [String, Number, Boolean, Array, Date],
22 | // 计算后的值
23 | computedValue: [String, Number, Boolean, Array, Date],
24 | // 显示的值
25 | displayValue: [String, Number, Boolean, Array, Date],
26 | // 是否不需要包裹
27 | noWrapper: {
28 | type: Boolean,
29 | required: true
30 | }
31 | },
32 | computed: {
33 | // 全局参数
34 | globalEditableParams () {
35 | return this.$EleEditableParams || {}
36 | },
37 | // 组件属性: 默认属性和自定义属性的融合
38 | attrs () {
39 | return Object.assign(
40 | {},
41 | this.globalEditableParams[this.type] || {},
42 | this.defaultAttrs || {},
43 | this.customAttrs
44 | )
45 | },
46 | format () {
47 | let format =
48 | this.attrs && this.attrs.format ? this.attrs.format : 'yyyy-MM-dd'
49 | format = format.replace(/Y/g, 'y')
50 | format = format.replace(/D/g, 'd')
51 | return format
52 | },
53 | showFormat () {
54 | let format =
55 | this.attrs && this.attrs.format ? this.attrs.format : 'yyyy-MM-dd'
56 | format = format.replace(/y/g, 'Y')
57 | format = format.replace(/d/g, 'D')
58 | return format
59 | }
60 | },
61 | data () {
62 | return {
63 | // 用于组件 v-model 绑定值
64 | newValue: this.computedValue
65 | }
66 | },
67 | watch: {
68 | // 检测是否出错, 出错后进行还原值
69 | isError (value) {
70 | if (value) {
71 | this.setNewValue()
72 | }
73 | },
74 | // 当检测到值变化时, 进行设置新值
75 | computedValue () {
76 | this.setNewValue()
77 | }
78 | },
79 | methods: {
80 | // 设置新值
81 | setNewValue () {
82 | this.newValue = this.computedValue
83 | },
84 | // 提交
85 | handleChange (value) {
86 | if (this.noWrapper) {
87 | this.$emit('change', value)
88 | } else {
89 | this.$emit('update', value)
90 | }
91 | },
92 | // 取消(还原值)
93 | handleCancel () {
94 | this.setNewValue()
95 | },
96 | // 日期和时间特殊处理
97 | setTimeNewValue () {
98 | const value =
99 | typeof this.computedValue === 'number'
100 | ? this.computedValue * 1000
101 | : this.computedValue
102 | if (dayjs(value).isValid()) {
103 | this.newValue = dayjs(value).format(this.showFormat)
104 | } else {
105 | this.newValue = value
106 | }
107 | },
108 | // 日期和时间特殊处理
109 | handleTimeChange (value) {
110 | if (value) {
111 | if (typeof this.value === 'number') {
112 | value = dayjs(value).unix()
113 | } else {
114 | if (dayjs(value).isValid()) {
115 | value = dayjs(value).format(this.showFormat)
116 | }
117 | }
118 | }
119 | this.handleChange(value)
120 | }
121 | },
122 | mounted () {
123 | // 初始化
124 | this.setNewValue()
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/EleEditableWrapper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
20 |
21 |
22 |
28 |
33 |
34 |
35 |
36 |
37 |
38 |
43 |
44 |
50 |
51 |
52 |
53 | 取消
57 | 确定
62 |
63 |
64 |
65 |
66 |
67 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
88 |
89 |
90 |
91 |
92 |
93 |
206 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/src/EleEditable.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
26 |
42 |
43 |
44 |
45 |
46 |
353 |
354 |
378 |
--------------------------------------------------------------------------------
/example/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
vue-ele-editable
4 | 类型演示:
5 |
10 |
15 |
20 |
24 |
25 |
35 |
36 |
37 |
41 |
42 |
53 |
54 |
55 |
56 |
57 | 案例:
58 |
63 |
70 |
71 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
500 |
--------------------------------------------------------------------------------