Commit 52a3208c9c7bd5ef3a634be490df5af0f2d334bc

Authored by 刘汉宸
1 parent b52e633c

feat: 优化Table组件更新文档

examples/mixins/origin.js
... ... @@ -46,5 +46,12 @@ export default {
46 46 }
47 47 return newObj;
48 48 },
  49 + // 获取初始值
  50 + getOriginData(key) {
  51 + if (key) {
  52 + return this.cloneDeep(this.originData)[key];
  53 + }
  54 + return this.cloneDeep(this.originData);
  55 + },
49 56 },
50 57 };
... ...
examples/mixins/page.js
1   -import MIX_TOAST from '@/mixins/toast';
2   -import MIX_ORIGIN from '@/mixins/origin';
  1 +import MIX_ORIGIN from '@/mixins/origin'; // 初始值逻辑混入
3 2  
4 3 export default {
5   - mixins: [MIX_TOAST, MIX_ORIGIN],
  4 + mixins: [MIX_ORIGIN],
6 5 data() {
7 6 return {
8   - auto: true,
9   - tableData: [],
10   - loading: false,
11   - total: 0,
12   - currentPage: 1,
13   - pageSize: 10,
14   - pageSizes: [10, 20, 50, 100],
15   - layout: 'total, sizes, prev, pager, next, jumper',
16   - searchModel: {},
17   - form: {},
18   - submitting: false,
19   - selection: [],
  7 + auto: true, // 页面加载时自动查询
  8 + tableData: [], // 表格数据
  9 + loading: false, // 加载状态
  10 + total: 0, // 数据总量
  11 + currentPage: 1, // 当前页码
  12 + pageSize: 10, // 分页大小
  13 + pageSizes: [10, 20, 50, 100], // 分页大小选项
  14 + layout: 'total, sizes, prev, pager, next, jumper', // 分页器默认设置
  15 + searchModel: {}, // 搜索表单绑定值
  16 + form: {}, // 常规表单绑定值
  17 + submitting: false, // 提交状态
  18 + selection: [], // 表格选中项
20 19 collapsed: false, // 展开状态
21 20 };
22 21 },
... ... @@ -94,8 +93,7 @@ export default {
94 93 this.loading = true;
95 94 const params = {
96 95 ...this.searchModel,
97   - currentPage: this.currentPage,
98   - pageSize: this.pageSize,
  96 + ...this.pageParams,
99 97 };
100 98 const searchAPI = this.searchAPI || this.emptyPromise;
101 99 await searchAPI(params)
... ...
examples/mixins/toast.js
... ... @@ -1,14 +0,0 @@
1   -export default {
2   - methods: {
3   - // 显示加载中提示框
4   - toast(config = {}) {
5   - return this.$loading({
6   - lock: true,
7   - text: '加载中...',
8   - spinner: 'el-icon-loading',
9   - customClass: 'el-loading-toast',
10   - ...config,
11   - });
12   - },
13   - },
14   -};
examples/router/routes.js
... ... @@ -114,13 +114,13 @@ _components.forEach(data => {
114 114  
115 115 const _develops = [
116 116 {
117   - group: '开发模式',
  117 + group: '混入开发',
118 118 children: [
119 119 {
120   - path: 'mixin',
121   - name: 'mixin',
122   - meta: { title: 'Mixin 混入' },
123   - component: () => import('@/views/docs/develop/mixin.md'),
  120 + path: 'page',
  121 + name: 'page',
  122 + meta: { title: 'Mixin Page 标准页' },
  123 + component: () => import('@/views/docs/develop/mixin/page.md'),
124 124 },
125 125 ],
126 126 },
... ...
examples/styles/variables.scss
1   -$primary: #3296fa;
  1 +$primary: #F39800;
2 2  
3 3 $blue: #2f54eb;
4 4 $blue-light: #69c0ff;
... ...
examples/views/docs/component/table.md
... ... @@ -36,21 +36,66 @@ export default {
36 36  
37 37 :::
38 38  
39   -## 可编辑表格
  39 +## 配置项
  40 +
  41 +可以通过配置项列表快速生成表格列
  42 +
  43 +::: snippet 设置`columns`配置表格列,插槽`header-列字段名`可自定义表头的内容,插槽`cell-列字段名`可自定义列单元格的内容。
  44 +
  45 +```html
  46 +<template>
  47 + <z-table :data="tableData" border size="small" :columns="columns">
  48 + <template #header-age>年龄 <i class="el-icon-question"></i></template>
  49 + <template #cell-gender="{ value }">
  50 + <el-tag size="mini">{{ value }}</el-tag>
  51 + </template>
  52 + </z-table>
  53 +</template>
  54 +
  55 +<script>
  56 +export default {
  57 + data() {
  58 + return {
  59 + tableData: [
  60 + { name: '张三', age: '31', gender: '男' },
  61 + { name: '李四', age: '27', gender: '女' },
  62 + { name: '王五', age: '16', gender: '男' },
  63 + ],
  64 + columns: [
  65 + { prop: 'name', label: '姓名' },
  66 + { prop: 'age', label: '年龄' },
  67 + { prop: 'gender', label: '性别' },
  68 + ]
  69 + };
  70 + },
  71 +}
  72 +</script>
  73 +```
  74 +
  75 +:::
  76 +
  77 +## 追加列
40 78  
41   -一般用于表格的静态数据编辑
  79 +使用配置项时,**新增的列**则默认追加在**配置项列**之后,使用`left`插槽可在表格的最左侧插入列,顺序在**配置项列**之前
42 80  
43   -::: snippet 设置type为`editable`开启可编辑模式
  81 +::: snippet 设置`columns`配置表格列,插槽`header-列字段名`可自定义表头的内容,插槽`cell-列字段名`可自定义列单元格的内容。
44 82  
45 83 ```html
46 84 <template>
47   - <z-table v-model="tableData" type="editable" border :columns="columns">
48   - <template #editor-gender="{ value, onInput }">
49   - <el-radio-group size="mini" :value="value" @input="onInput">
50   - <el-radio-button label="男">男</el-radio-button>
51   - <el-radio-button label="女">女</el-radio-button>
52   - </el-radio-group>
  85 + <z-table :data="tableData" border size="small" :columns="columns">
  86 + <template #left>
  87 + <el-table-column type="selection" width="40"></el-table-column>
  88 + <el-table-column label="左侧的列">
  89 + <template #default="{ $index }">
  90 + 内容 {{ $index }}
  91 + </template>
  92 + </el-table-column>
53 93 </template>
  94 + <el-table-column label="新增的列" width="80">
  95 + <template #default>
  96 + <el-button type="text">编辑</el-button>
  97 + </template>
  98 + </el-table-column>
54 99 </z-table>
55 100 </template>
56 101  
... ... @@ -59,18 +104,79 @@ export default {
59 104 data() {
60 105 return {
61 106 tableData: [
  107 + { name: '张三', age: '31', gender: '男' },
  108 + { name: '李四', age: '27', gender: '女' },
  109 + { name: '王五', age: '16', gender: '男' },
  110 + ],
  111 + columns: [
  112 + { prop: 'name', label: '姓名' },
  113 + { prop: 'age', label: '年龄' },
  114 + { prop: 'gender', label: '性别' },
  115 + ]
  116 + };
  117 + },
  118 +}
  119 +</script>
  120 +```
  121 +
  122 +:::
  123 +
  124 +## 可编辑表格
  125 +
  126 +一般用于表格的静态数据编辑,设置`editable`开启可编辑模式,设置`clickable`开启双击编辑
  127 +
  128 +::: snippet 编辑功能只支持通过`columns`配置的列,`editable`设置该列是否可编辑,默认开启;插槽`editor-列字段名`可自定义列单元格的编辑器,通过解构作用域插槽获取的`value`和`onInput`改变表格的绑定值,不支持直接写`v-model`。
  129 +
  130 +```html
  131 +<template>
  132 + <div>
  133 + <z-form span="6">
  134 + <z-form-item>编辑模式:<el-switch v-model="editable"></el-switch></z-form-item>
  135 + <z-form-item>双击编辑:<el-switch v-model="clickable"></el-switch></z-form-item>
  136 + </z-form>
  137 + <z-table v-model="tableData" :editable="editable" :columns="columns" border :clickable="clickable" @cell-edit-confirm="onCellEditConfirm">
  138 + <template #editor-gender="{ value, onInput, index }">
  139 + <el-radio-group size="mini" :value="value" @input="onInput">
  140 + <el-radio-button label="男">男</el-radio-button>
  141 + <el-radio-button label="女">女</el-radio-button>
  142 + </el-radio-group>
  143 + </template>
  144 + <el-table-column label="操作" width="80">
  145 + <template #default="{ $index }">
  146 + <el-button type="text" @click="deleteRow($index)">删除</el-button>
  147 + </template>
  148 + </el-table-column>
  149 + </z-table>
  150 + </div>
  151 +</template>
  152 +
  153 +<script>
  154 +export default {
  155 + data() {
  156 + return {
  157 + editable: true,
  158 + clickable: true,
  159 + tableData: [
62 160 { name: '张三', age: 31, gender: '男', remark: '' },
63 161 { name: '李四', age: 27, gender: '女', remark: '' },
64 162 { name: '王五', age: 16, gender: '男', remark: '' },
65 163 ],
66 164 columns: [
67 165 { prop: 'name', label: '姓名', editable: false },
68   - { type: 'el-input-number', prop: 'age', label: '年龄' },
  166 + { component: 'el-input-number', prop: 'age', label: '年龄' },
69 167 { prop: 'gender', label: '性别' },
70 168 { prop: 'remark', label: '备注' },
71 169 ]
72 170 };
73 171 },
  172 + methods: {
  173 + deleteRow(index) {
  174 + this.tableData.splice(index, 1);
  175 + },
  176 + onCellEditConfirm(data) {
  177 + console.log(data);
  178 + }
  179 + }
74 180 }
75 181 </script>
76 182 ```
... ...
examples/views/docs/develop/mixin.md
... ... @@ -1,62 +0,0 @@
1   -# Mixin 混入
2   -
3   -根据JSON Scheme配置自动生成一个筛选条件表单
4   -
5   -## 基础用法
6   -
7   -配置`list`属性设置JSON Scheme配置列表
8   -
9   -::: snippet 通过`list`配置项目
10   -
11   -```html
12   -<template>
13   - <div>
14   - <div class="page-search">
15   - <el-form :model="searchModel" label-width="80px" size="small">
16   - <el-row>
17   - <el-col :span="6">
18   - <el-form-item label="姓名">
19   - <el-input v-model.trim="searchModel.name"></el-input>
20   - </el-form-item>
21   - </el-col>
22   - <el-col :span="6">
23   - <el-form-item label="手机号">
24   - <el-input v-model.trim="searchModel.mobile"></el-input>
25   - </el-form-item>
26   - </el-col>
27   - </el-row>
28   - </el-form>
29   - </div>
30   - <div class="page-action">
31   - <el-button type="primary" size="small">新增</el-button>
32   - </div>
33   - <el-table class="page-table" v-loading="loading" size="small" :data="tableData" border highlight-current-row>
34   - <el-table-column label="姓名" prop="name" min-width="100" show-overflow-tooltip></el-table-column>
35   - <el-table-column label="手机号" prop="mobile" min-width="120" show-overflow-tooltip></el-table-column>
36   - </el-table>
37   - <el-pagination class="page-pagination" v-bind="paginationProps" v-on="paginationEvent"></el-pagination>
38   - </div>
39   -</template>
40   -
41   -<script>
42   -// import MIX_PAGE from '@/mixins/page';
43   -
44   -export default {
45   - // mixins: [MIX_PAGE],
46   - mixins: [window.MIX_PAGE],
47   - data() {
48   - return {
49   - searchModel: {
50   - name: '',
51   - mobile: '',
52   - },
53   - };
54   - },
55   - methods: {
56   - },
57   -};
58   -</script>
59   -
60   -```
61   -
62   -:::
63 0 \ No newline at end of file
examples/views/docs/develop/mixin/page.md 0 → 100644
... ... @@ -0,0 +1,331 @@
  1 +# Mixin Page 标准页
  2 +
  3 +根据JSON Scheme配置自动生成一个筛选条件表单
  4 +
  5 +## 基础用法
  6 +
  7 +`MIX_PAGE`混入配置项,会默认提供一套分页查询的业务逻辑。
  8 +
  9 +::: snippet 预置了许多业务逻辑,避免重复维护相同的业务逻辑
  10 +
  11 +```html
  12 +<template>
  13 + <div>
  14 + <div class="page-search">
  15 + <el-form :model="searchModel" label-width="80px" size="small">
  16 + <el-row>
  17 + <el-col :span="6">
  18 + <el-form-item label="姓名">
  19 + <el-input v-model.trim="searchModel.name"></el-input>
  20 + </el-form-item>
  21 + </el-col>
  22 + <el-col :span="18" style="text-align: right;">
  23 + <el-form-item>
  24 + <el-button-group>
  25 + <el-button :loading="loading" type="primary" @click="onSearch">查询</el-button>
  26 + <el-button @click="onReset">重置</el-button>
  27 + </el-button-group>
  28 + </el-form-item>
  29 + </el-col>
  30 + </el-row>
  31 + </el-form>
  32 + </div>
  33 + <div class="page-action">
  34 + <el-button type="primary" size="small">新增</el-button>
  35 + </div>
  36 + <el-table class="page-table" v-loading="loading" v-bind="tableProps" :data="tableData">
  37 + <el-table-column label="姓名" prop="name" min-width="100" show-overflow-tooltip></el-table-column>
  38 + <el-table-column label="年龄" prop="age" min-width="120" show-overflow-tooltip></el-table-column>
  39 + </el-table>
  40 + <el-pagination class="page-pagination" v-bind="paginationProps" v-on="paginationEvent"></el-pagination>
  41 + </div>
  42 +</template>
  43 +
  44 +<script>
  45 +// import MIX_PAGE from '@/mixins/page'; 注:使用时解除此注释
  46 +
  47 +export default {
  48 + mixins: [MIX_PAGE],
  49 + data() {
  50 + return {
  51 + searchModel: {
  52 + name: '',
  53 + },
  54 + };
  55 + },
  56 + methods: {
  57 + searchAPI(params) {
  58 + return new Promise(resolve => {
  59 + setTimeout(() => {
  60 + const source = [
  61 + { id: '0', name: '李饼', age: 32 },
  62 + { id: '1', name: '陈拾', age: 20 },
  63 + { id: '3', name: '王七', age: 26 },
  64 + { id: '4', name: '崔倍', age: 27 },
  65 + { id: '5', name: '孙豹', age: 38 },
  66 + { id: '6', name: '庞柏', age: 42 },
  67 + { id: '7', name: '蔡疏', age: 60 },
  68 + { id: '8', name: '卢纳', age: 55 },
  69 + ];
  70 + const list = source.filter(item => `${item.name}`.includes(params.name));
  71 + resolve({
  72 + result: list,
  73 + totalCount: list.length
  74 + });
  75 + }, 1500);
  76 + });
  77 + },
  78 + },
  79 +};
  80 +</script>
  81 +
  82 +```
  83 +
  84 +:::
  85 +
  86 +## 推荐用法
  87 +
  88 +与`z-form`、`z-table`等组件配合,可以最大限度的减少代码量,开发者只需要重点关心与业务相关的数据渲染
  89 +
  90 +::: snippet `MIX_PAGE`混入配置项,会默认提供一套分页查询的业务逻辑。
  91 +
  92 +```html
  93 +<template>
  94 + <div>
  95 + <div class="page-search">
  96 + <z-form :model="searchModel" label-width="80px" size="small" span="6">
  97 + <z-form-item label="姓名" prop="name">
  98 + <el-input v-model="searchModel.name"></el-input>
  99 + </z-form-item>
  100 + <z-form-item span="18" style="text-align: right">
  101 + <el-button-group>
  102 + <el-button :loading="loading" type="primary" @click="onSearch">查询</el-button>
  103 + <el-button @click="onReset">重置</el-button>
  104 + </el-button-group>
  105 + </z-form-item>
  106 + </z-form>
  107 + </div>
  108 + <div class="page-action">
  109 + <el-button type="primary" size="small">新增</el-button>
  110 + </div>
  111 + <z-table class="page-table" v-loading="loading" v-bind="tableProps">
  112 + <el-table-column prop="name" label="姓名"></el-table-column>
  113 + <el-table-column prop="age" label="年龄"></el-table-column>
  114 + </z-table>
  115 + <el-pagination class="page-pagination" v-bind="paginationProps" v-on="paginationEvent"></el-pagination>
  116 + </div>
  117 +</template>
  118 +
  119 +<script>
  120 +// import MIX_PAGE from '@/mixins/page'; 注:使用时解除此注释
  121 +
  122 +export default {
  123 + mixins: [MIX_PAGE],
  124 + data() {
  125 + return {
  126 + searchModel: {
  127 + name: '',
  128 + },
  129 + };
  130 + },
  131 + methods: {
  132 + searchAPI(params) {
  133 + return new Promise(resolve => {
  134 + setTimeout(() => {
  135 + const source = [
  136 + { id: '0', name: '李饼', age: 32 },
  137 + { id: '1', name: '陈拾', age: 20 },
  138 + { id: '3', name: '王七', age: 26 },
  139 + { id: '4', name: '崔倍', age: 27 },
  140 + { id: '5', name: '孙豹', age: 38 },
  141 + { id: '6', name: '庞柏', age: 42 },
  142 + { id: '7', name: '蔡疏', age: 60 },
  143 + { id: '8', name: '卢纳', age: 55 },
  144 + ];
  145 + const list = source.filter(item => `${item.name}`.includes(params.name));
  146 + resolve({
  147 + result: list,
  148 + totalCount: list.length
  149 + });
  150 + }, 1500);
  151 + });
  152 + },
  153 + },
  154 +};
  155 +</script>
  156 +
  157 +```
  158 +
  159 +:::
  160 +
  161 +## 内置方法
  162 +
  163 +本混入配置中,内置了`originData`对象和`getOriginData`方法。
  164 +
  165 +::: snippet `originData`表示当前页面的初始data值,`getOriginData`方法可获得一个新的初始值对象
  166 +
  167 +```html
  168 +<template>
  169 + <div>
  170 + <div>model初始值:{{ originData.model }}</div>
  171 + <el-input v-model="model.name" size="mini" style="width: 200px; margin: 10px 0"></el-input>
  172 + <el-button type="primary" size="mini" @click="handleReset">重置</el-button>
  173 + <div>model当前值:{{ model }}</div>
  174 + </div>
  175 +</template>
  176 +
  177 +<script>
  178 +export default {
  179 + mixins: [MIX_PAGE],
  180 + data() {
  181 + return {
  182 + model: {
  183 + name: '张三',
  184 + },
  185 + };
  186 + },
  187 + methods: {
  188 + handleReset() {
  189 + // 注意:切记不可写成 this.model = this.originData.model; 否则会导致originData被改变!
  190 + this.model = this.getOriginData().model;
  191 + }
  192 + },
  193 +};
  194 +</script>
  195 +```
  196 +
  197 +:::
  198 +
  199 +## 源文件
  200 +
  201 +```js
  202 +import MIX_ORIGIN from '@/mixins/origin'; // 初始值逻辑混入
  203 +
  204 +export default {
  205 + mixins: [MIX_ORIGIN],
  206 + data() {
  207 + return {
  208 + auto: true, // 页面加载时自动查询
  209 + tableData: [], // 表格数据
  210 + loading: false, // 加载状态
  211 + total: 0, // 数据总量
  212 + currentPage: 1, // 当前页码
  213 + pageSize: 10, // 分页大小
  214 + pageSizes: [10, 20, 50, 100], // 分页大小选项
  215 + layout: 'total, sizes, prev, pager, next, jumper', // 分页器默认设置
  216 + searchModel: {}, // 搜索表单绑定值
  217 + form: {}, // 常规表单绑定值
  218 + submitting: false, // 提交状态
  219 + selection: [], // 表格选中项
  220 + collapsed: false, // 展开状态
  221 + };
  222 + },
  223 + computed: {
  224 + // 搜索栏折叠按钮文本
  225 + toggleText() {
  226 + return this.collapsed ? '收起' : '展开';
  227 + },
  228 + // 表格属性
  229 + tableProps() {
  230 + return {
  231 + size: 'mini',
  232 + rowKey: 'id',
  233 + border: true,
  234 + highlightCurrentRow: true,
  235 + data: this.tableData,
  236 + };
  237 + },
  238 + // 表格事件
  239 + tableEvent() {
  240 + return {
  241 + 'selection-change': this.onSelectionChange,
  242 + };
  243 + },
  244 + // 分页参数
  245 + pageParams() {
  246 + return {
  247 + currentPage: this.currentPage,
  248 + pageSize: this.pageSize,
  249 + };
  250 + },
  251 + // 分页器属性
  252 + paginationProps() {
  253 + return {
  254 + 'current-page': this.currentPage,
  255 + 'page-sizes': this.pageSizes,
  256 + 'page-size': this.pageSize,
  257 + layout: this.layout,
  258 + total: this.total,
  259 + };
  260 + },
  261 + // 分页器事件
  262 + paginationEvent() {
  263 + return {
  264 + 'size-change': this.onPageSizeChange,
  265 + 'current-change': this.onCurrentPageChange,
  266 + };
  267 + },
  268 + },
  269 + created() {
  270 + if (this.auto) {
  271 + this.search();
  272 + }
  273 + },
  274 + methods: {
  275 + // 空Promise
  276 + emptyPromise() {
  277 + return new Promise(resolve => resolve());
  278 + },
  279 + // 重置查询
  280 + onSearch() {
  281 + this.currentPage = 1;
  282 + this.loadData();
  283 + },
  284 + // 切换展开状态
  285 + toggle() {
  286 + this.collapsed = !this.collapsed;
  287 + },
  288 + // 查询数据
  289 + search() {
  290 + this.loadData();
  291 + },
  292 + // 加载数据
  293 + async loadData() {
  294 + this.loading = true;
  295 + const params = {
  296 + ...this.searchModel,
  297 + ...this.pageParams,
  298 + };
  299 + const searchAPI = this.searchAPI || this.emptyPromise;
  300 + await searchAPI(params)
  301 + .then(response => {
  302 + const { result = [], totalCount = 0 } = response || {};
  303 + this.tableData = result || [];
  304 + this.total = totalCount || 0;
  305 + })
  306 + .finally(() => {
  307 + this.loading = false;
  308 + });
  309 + },
  310 + // 重置搜索表单
  311 + onReset() {
  312 + this.searchModel = this.cloneDeep(this.originData).searchModel;
  313 + },
  314 + // 多选
  315 + onSelectionChange(selection) {
  316 + this.selection = selection;
  317 + },
  318 + // 切换当前页码
  319 + onCurrentPageChange(value) {
  320 + this.currentPage = value;
  321 + this.$nextTick(this.loadData);
  322 + },
  323 + // 切换最大页码
  324 + onPageSizeChange(value) {
  325 + this.currentPage = 1;
  326 + this.pageSize = value;
  327 + this.$nextTick(this.loadData);
  328 + },
  329 + },
  330 +};
  331 +```
0 332 \ No newline at end of file
... ...
packages/table/editable.vue
... ... @@ -28,6 +28,7 @@
28 28  
29 29 <template>
30 30 <el-table :data="tableData | tableDataFilter" :size="tableSize" v-bind="_props" @header-click="onHeaderClick" @cell-click="onCellClick" @cell-dblclick="onCellDblclick">
  31 + <slot name="left"></slot>
31 32 <template v-for="(item, index) in columns">
32 33 <el-table-column v-bind="item" :key="index">
33 34 <slot :name="`header-${item.prop}`" slot="header"></slot>
... ... @@ -35,11 +36,11 @@
35 36 <cell-editor
36 37 :disabled="disabled || item.editable === false"
37 38 :editable="item.editable !== false && (row.$editable || (tableEditCell.index === row.$index && tableEditCell.prop === item.prop))"
38   - :type="item.type"
  39 + :component="item.component"
39 40 :value="row[column.property]"
40 41 @input="onCellInput"
41 42 @edit-click="setEditCell(row, column)"
42   - @edit-confirm="cancelEditCell"
  43 + @edit-confirm="onEditConfirm"
43 44 >
44 45 <template v-if="$scopedSlots[`editor-${item.prop}`]">
45 46 <slot :name="`editor-${item.prop}`" :value="row[column.property]" :onInput="onCellInput"></slot>
... ... @@ -48,6 +49,8 @@
48 49 </template>
49 50 </el-table-column>
50 51 </template>
  52 + <slot></slot>
  53 + <slot name="append"></slot>
51 54 </el-table>
52 55 </template>
53 56  
... ... @@ -63,13 +66,13 @@ export default {
63 66 cellEditor: {
64 67 props: {
65 68 value: [String, Number, Array, Object],
66   - type: { type: String, default: 'el-input' },
  69 + component: { type: String, default: 'el-input' },
67 70 editable: Boolean,
68 71 disabled: Boolean,
69 72 },
70 73 watch: {
71 74 editable(val) {
72   - if (val && this.type === 'el-input') {
  75 + if (val && this.component === 'el-input') {
73 76 this.$nextTick(() => {
74 77 this.$children[0] && this.$children[0].focus && this.$children[0].focus();
75 78 });
... ... @@ -79,7 +82,7 @@ export default {
79 82 render(h) {
80 83 if (this.editable) {
81 84 let editorRender = [
82   - h(this.type, {
  85 + h(this.component, {
83 86 props: { value: this.value, size: 'mini' },
84 87 on: {
85 88 input: value => {
... ... @@ -92,7 +95,7 @@ export default {
92 95 editorRender = [this.$scopedSlots.default()];
93 96 }
94 97 if (!this.disabled) {
95   - const handlerItems = [h('i', { attrs: { title: '确定', class: 'el-icon-check' }, on: { click: () => this.$emit('edit-confirm') } })];
  98 + const handlerItems = [h('i', { attrs: { title: '确定', class: 'el-icon-check' }, on: { click: () => this.$emit('edit-confirm', this.value) } })];
96 99 // handlerItems.push(h('i', { attrs: { title: '取消', class: 'el-icon-close' }, on: { click: () => this.$emit('edit-confirm') } }));
97 100 const handler = h('span', handlerItems);
98 101 editorRender.push(handler);
... ... @@ -163,6 +166,10 @@ export default {
163 166 setEditCell(row, column) {
164 167 this.tableEditCell = { index: row.$index, prop: column.property };
165 168 },
  169 + onEditConfirm(value) {
  170 + this.$emit('cell-edit-confirm', { ...this.tableEditCell, value });
  171 + this.cancelEditCell();
  172 + },
166 173 cancelEditCell() {
167 174 this.tableEditCell = {};
168 175 },
... ...
packages/table/index.js
... ... @@ -3,10 +3,6 @@ import tableProps from &#39;./props&#39;;
3 3 export default {
4 4 name: 'Table',
5 5 props: {
6   - type: {
7   - type: String,
8   - default: 'normal',
9   - },
10 6 value: {
11 7 type: Array,
12 8 default() {
... ... @@ -19,12 +15,14 @@ export default {
19 15 return [];
20 16 },
21 17 },
  18 + editable: Boolean,
22 19 clickable: Boolean,
23 20 disabled: Boolean,
24 21 ...tableProps,
25 22 },
26 23 render(h) {
27 24 const scopedSlots = this.$scopedSlots;
28   - return h(`z-table-${this.type}`, { props: { ...this._props }, scopedSlots });
  25 + const listeners = this.$listeners;
  26 + return h(`z-table-${this.editable ? 'editable' : 'normal'}`, { props: { ...this._props }, scopedSlots, on: listeners });
29 27 },
30 28 };
... ...
packages/table/normal.vue
1 1 <template>
2   - <el-table :size="tableSize" v-bind="_props">
  2 + <el-table :data="tableData" :size="tableSize" v-bind="_props">
  3 + <slot name="left"></slot>
  4 + <template v-for="(item, index) in columns">
  5 + <el-table-column v-bind="item" :key="index">
  6 + <slot :name="`header-${item.prop}`" slot="header"></slot>
  7 + <template v-if="$scopedSlots[`cell-${item.prop}`]" #default="{ row, column, $index }">
  8 + <slot :name="`cell-${item.prop}`" :value="row[column.property]" :row="row" :index="$index"></slot>
  9 + </template>
  10 + </el-table-column>
  11 + </template>
3 12 <slot></slot>
4 13 <slot name="append"></slot>
5 14 </el-table>
... ... @@ -19,8 +28,30 @@ export default {
19 28 },
20 29 },
21 30 props: {
  31 + value: {
  32 + type: Array,
  33 + default() {
  34 + return [];
  35 + },
  36 + },
  37 + columns: {
  38 + type: Array,
  39 + default() {
  40 + return [];
  41 + },
  42 + },
22 43 ...tableProps,
23 44 },
  45 + data() {
  46 + return {
  47 + tableData: this.value.length > 0 ? this.value : this.data,
  48 + };
  49 + },
  50 + watch: {
  51 + value(val) {
  52 + this.tableData = val || [];
  53 + },
  54 + },
24 55 computed: {
25 56 _elFormItemSize() {
26 57 return (this.elFormItem || {}).elFormItemSize;
... ...