diff --git a/examples/mixins/origin.js b/examples/mixins/origin.js index d4333d7..0fdc889 100644 --- a/examples/mixins/origin.js +++ b/examples/mixins/origin.js @@ -46,5 +46,12 @@ export default { } return newObj; }, + // 获取初始值 + getOriginData(key) { + if (key) { + return this.cloneDeep(this.originData)[key]; + } + return this.cloneDeep(this.originData); + }, }, }; diff --git a/examples/mixins/page.js b/examples/mixins/page.js index df3cbc6..69f6101 100644 --- a/examples/mixins/page.js +++ b/examples/mixins/page.js @@ -1,22 +1,21 @@ -import MIX_TOAST from '@/mixins/toast'; -import MIX_ORIGIN from '@/mixins/origin'; +import MIX_ORIGIN from '@/mixins/origin'; // 初始值逻辑混入 export default { - mixins: [MIX_TOAST, MIX_ORIGIN], + mixins: [MIX_ORIGIN], data() { return { - auto: true, - tableData: [], - loading: false, - total: 0, - currentPage: 1, - pageSize: 10, - pageSizes: [10, 20, 50, 100], - layout: 'total, sizes, prev, pager, next, jumper', - searchModel: {}, - form: {}, - submitting: false, - selection: [], + auto: true, // 页面加载时自动查询 + tableData: [], // 表格数据 + loading: false, // 加载状态 + total: 0, // 数据总量 + currentPage: 1, // 当前页码 + pageSize: 10, // 分页大小 + pageSizes: [10, 20, 50, 100], // 分页大小选项 + layout: 'total, sizes, prev, pager, next, jumper', // 分页器默认设置 + searchModel: {}, // 搜索表单绑定值 + form: {}, // 常规表单绑定值 + submitting: false, // 提交状态 + selection: [], // 表格选中项 collapsed: false, // 展开状态 }; }, @@ -94,8 +93,7 @@ export default { this.loading = true; const params = { ...this.searchModel, - currentPage: this.currentPage, - pageSize: this.pageSize, + ...this.pageParams, }; const searchAPI = this.searchAPI || this.emptyPromise; await searchAPI(params) diff --git a/examples/mixins/toast.js b/examples/mixins/toast.js deleted file mode 100644 index 3227aaa..0000000 --- a/examples/mixins/toast.js +++ /dev/null @@ -1,14 +0,0 @@ -export default { - methods: { - // 显示加载中提示框 - toast(config = {}) { - return this.$loading({ - lock: true, - text: '加载中...', - spinner: 'el-icon-loading', - customClass: 'el-loading-toast', - ...config, - }); - }, - }, -}; diff --git a/examples/router/routes.js b/examples/router/routes.js index 6e25762..47d6498 100644 --- a/examples/router/routes.js +++ b/examples/router/routes.js @@ -114,13 +114,13 @@ _components.forEach(data => { const _develops = [ { - group: '开发模式', + group: '混入开发', children: [ { - path: 'mixin', - name: 'mixin', - meta: { title: 'Mixin 混入' }, - component: () => import('@/views/docs/develop/mixin.md'), + path: 'page', + name: 'page', + meta: { title: 'Mixin Page 标准页' }, + component: () => import('@/views/docs/develop/mixin/page.md'), }, ], }, diff --git a/examples/styles/variables.scss b/examples/styles/variables.scss index dfd390e..971235f 100644 --- a/examples/styles/variables.scss +++ b/examples/styles/variables.scss @@ -1,4 +1,4 @@ -$primary: #3296fa; +$primary: #F39800; $blue: #2f54eb; $blue-light: #69c0ff; diff --git a/examples/views/docs/component/table.md b/examples/views/docs/component/table.md index 9bb6306..6a2a360 100644 --- a/examples/views/docs/component/table.md +++ b/examples/views/docs/component/table.md @@ -36,21 +36,66 @@ export default { ::: -## 可编辑表格 +## 配置项 + +可以通过配置项列表快速生成表格列 + +::: snippet 设置`columns`配置表格列,插槽`header-列字段名`可自定义表头的内容,插槽`cell-列字段名`可自定义列单元格的内容。 + +```html + + + 年龄 + + {{ value }} + + + + + +``` + +::: + +## 追加列 -一般用于表格的静态数据编辑 +使用配置项时,**新增的列**则默认追加在**配置项列**之后,使用`left`插槽可在表格的最左侧插入列,顺序在**配置项列**之前 -::: snippet 设置type为`editable`开启可编辑模式 +::: snippet 设置`columns`配置表格列,插槽`header-列字段名`可自定义表头的内容,插槽`cell-列字段名`可自定义列单元格的内容。 ```html - - - - 男 - 女 - + + + + + + 内容 {{ $index }} + + + + + 编辑 + + @@ -59,18 +104,79 @@ export default { data() { return { tableData: [ + { name: '张三', age: '31', gender: '男' }, + { name: '李四', age: '27', gender: '女' }, + { name: '王五', age: '16', gender: '男' }, + ], + columns: [ + { prop: 'name', label: '姓名' }, + { prop: 'age', label: '年龄' }, + { prop: 'gender', label: '性别' }, + ] + }; + }, +} + +``` + +::: + +## 可编辑表格 + +一般用于表格的静态数据编辑,设置`editable`开启可编辑模式,设置`clickable`开启双击编辑 + +::: snippet 编辑功能只支持通过`columns`配置的列,`editable`设置该列是否可编辑,默认开启;插槽`editor-列字段名`可自定义列单元格的编辑器,通过解构作用域插槽获取的`value`和`onInput`改变表格的绑定值,不支持直接写`v-model`。 + +```html + + + + 编辑模式: + 双击编辑: + + + + + 男 + 女 + + + + + 删除 + + + + + + + ``` diff --git a/examples/views/docs/develop/mixin.md b/examples/views/docs/develop/mixin.md deleted file mode 100644 index 6345473..0000000 --- a/examples/views/docs/develop/mixin.md +++ /dev/null @@ -1,62 +0,0 @@ -# Mixin 混入 - -根据JSON Scheme配置自动生成一个筛选条件表单 - -## 基础用法 - -配置`list`属性设置JSON Scheme配置列表 - -::: snippet 通过`list`配置项目 - -```html - - - - - - - - - - - - - - - - - - - - 新增 - - - - - - - - - - - -``` - -::: \ No newline at end of file diff --git a/examples/views/docs/develop/mixin/page.md b/examples/views/docs/develop/mixin/page.md new file mode 100644 index 0000000..3a138a4 --- /dev/null +++ b/examples/views/docs/develop/mixin/page.md @@ -0,0 +1,331 @@ +# Mixin Page 标准页 + +根据JSON Scheme配置自动生成一个筛选条件表单 + +## 基础用法 + +`MIX_PAGE`混入配置项,会默认提供一套分页查询的业务逻辑。 + +::: snippet 预置了许多业务逻辑,避免重复维护相同的业务逻辑 + +```html + + + + + + + + + + + + + + 查询 + 重置 + + + + + + + + 新增 + + + + + + + + + + + +``` + +::: + +## 推荐用法 + +与`z-form`、`z-table`等组件配合,可以最大限度的减少代码量,开发者只需要重点关心与业务相关的数据渲染 + +::: snippet `MIX_PAGE`混入配置项,会默认提供一套分页查询的业务逻辑。 + +```html + + + + + + + + + + 查询 + 重置 + + + + + + 新增 + + + + + + + + + + + +``` + +::: + +## 内置方法 + +本混入配置中,内置了`originData`对象和`getOriginData`方法。 + +::: snippet `originData`表示当前页面的初始data值,`getOriginData`方法可获得一个新的初始值对象 + +```html + + + model初始值:{{ originData.model }} + + 重置 + model当前值:{{ model }} + + + + +``` + +::: + +## 源文件 + +```js +import MIX_ORIGIN from '@/mixins/origin'; // 初始值逻辑混入 + +export default { + mixins: [MIX_ORIGIN], + data() { + return { + auto: true, // 页面加载时自动查询 + tableData: [], // 表格数据 + loading: false, // 加载状态 + total: 0, // 数据总量 + currentPage: 1, // 当前页码 + pageSize: 10, // 分页大小 + pageSizes: [10, 20, 50, 100], // 分页大小选项 + layout: 'total, sizes, prev, pager, next, jumper', // 分页器默认设置 + searchModel: {}, // 搜索表单绑定值 + form: {}, // 常规表单绑定值 + submitting: false, // 提交状态 + selection: [], // 表格选中项 + collapsed: false, // 展开状态 + }; + }, + computed: { + // 搜索栏折叠按钮文本 + toggleText() { + return this.collapsed ? '收起' : '展开'; + }, + // 表格属性 + tableProps() { + return { + size: 'mini', + rowKey: 'id', + border: true, + highlightCurrentRow: true, + data: this.tableData, + }; + }, + // 表格事件 + tableEvent() { + return { + 'selection-change': this.onSelectionChange, + }; + }, + // 分页参数 + pageParams() { + return { + currentPage: this.currentPage, + pageSize: this.pageSize, + }; + }, + // 分页器属性 + paginationProps() { + return { + 'current-page': this.currentPage, + 'page-sizes': this.pageSizes, + 'page-size': this.pageSize, + layout: this.layout, + total: this.total, + }; + }, + // 分页器事件 + paginationEvent() { + return { + 'size-change': this.onPageSizeChange, + 'current-change': this.onCurrentPageChange, + }; + }, + }, + created() { + if (this.auto) { + this.search(); + } + }, + methods: { + // 空Promise + emptyPromise() { + return new Promise(resolve => resolve()); + }, + // 重置查询 + onSearch() { + this.currentPage = 1; + this.loadData(); + }, + // 切换展开状态 + toggle() { + this.collapsed = !this.collapsed; + }, + // 查询数据 + search() { + this.loadData(); + }, + // 加载数据 + async loadData() { + this.loading = true; + const params = { + ...this.searchModel, + ...this.pageParams, + }; + const searchAPI = this.searchAPI || this.emptyPromise; + await searchAPI(params) + .then(response => { + const { result = [], totalCount = 0 } = response || {}; + this.tableData = result || []; + this.total = totalCount || 0; + }) + .finally(() => { + this.loading = false; + }); + }, + // 重置搜索表单 + onReset() { + this.searchModel = this.cloneDeep(this.originData).searchModel; + }, + // 多选 + onSelectionChange(selection) { + this.selection = selection; + }, + // 切换当前页码 + onCurrentPageChange(value) { + this.currentPage = value; + this.$nextTick(this.loadData); + }, + // 切换最大页码 + onPageSizeChange(value) { + this.currentPage = 1; + this.pageSize = value; + this.$nextTick(this.loadData); + }, + }, +}; +``` \ No newline at end of file diff --git a/packages/table/editable.vue b/packages/table/editable.vue index f07643f..700dd0b 100644 --- a/packages/table/editable.vue +++ b/packages/table/editable.vue @@ -28,6 +28,7 @@ + @@ -35,11 +36,11 @@ @@ -48,6 +49,8 @@ + + @@ -63,13 +66,13 @@ export default { cellEditor: { props: { value: [String, Number, Array, Object], - type: { type: String, default: 'el-input' }, + component: { type: String, default: 'el-input' }, editable: Boolean, disabled: Boolean, }, watch: { editable(val) { - if (val && this.type === 'el-input') { + if (val && this.component === 'el-input') { this.$nextTick(() => { this.$children[0] && this.$children[0].focus && this.$children[0].focus(); }); @@ -79,7 +82,7 @@ export default { render(h) { if (this.editable) { let editorRender = [ - h(this.type, { + h(this.component, { props: { value: this.value, size: 'mini' }, on: { input: value => { @@ -92,7 +95,7 @@ export default { editorRender = [this.$scopedSlots.default()]; } if (!this.disabled) { - const handlerItems = [h('i', { attrs: { title: '确定', class: 'el-icon-check' }, on: { click: () => this.$emit('edit-confirm') } })]; + const handlerItems = [h('i', { attrs: { title: '确定', class: 'el-icon-check' }, on: { click: () => this.$emit('edit-confirm', this.value) } })]; // handlerItems.push(h('i', { attrs: { title: '取消', class: 'el-icon-close' }, on: { click: () => this.$emit('edit-confirm') } })); const handler = h('span', handlerItems); editorRender.push(handler); @@ -163,6 +166,10 @@ export default { setEditCell(row, column) { this.tableEditCell = { index: row.$index, prop: column.property }; }, + onEditConfirm(value) { + this.$emit('cell-edit-confirm', { ...this.tableEditCell, value }); + this.cancelEditCell(); + }, cancelEditCell() { this.tableEditCell = {}; }, diff --git a/packages/table/index.js b/packages/table/index.js index a0e0d52..f2f38f6 100644 --- a/packages/table/index.js +++ b/packages/table/index.js @@ -3,10 +3,6 @@ import tableProps from './props'; export default { name: 'Table', props: { - type: { - type: String, - default: 'normal', - }, value: { type: Array, default() { @@ -19,12 +15,14 @@ export default { return []; }, }, + editable: Boolean, clickable: Boolean, disabled: Boolean, ...tableProps, }, render(h) { const scopedSlots = this.$scopedSlots; - return h(`z-table-${this.type}`, { props: { ...this._props }, scopedSlots }); + const listeners = this.$listeners; + return h(`z-table-${this.editable ? 'editable' : 'normal'}`, { props: { ...this._props }, scopedSlots, on: listeners }); }, }; diff --git a/packages/table/normal.vue b/packages/table/normal.vue index d341fca..429848c 100644 --- a/packages/table/normal.vue +++ b/packages/table/normal.vue @@ -1,5 +1,14 @@ - + + + + + + + + + + @@ -19,8 +28,30 @@ export default { }, }, props: { + value: { + type: Array, + default() { + return []; + }, + }, + columns: { + type: Array, + default() { + return []; + }, + }, ...tableProps, }, + data() { + return { + tableData: this.value.length > 0 ? this.value : this.data, + }; + }, + watch: { + value(val) { + this.tableData = val || []; + }, + }, computed: { _elFormItemSize() { return (this.elFormItem || {}).elFormItemSize; -- libgit2 0.21.0