Browse Source

feat(table): tableData customrender by Columns.render (#1234)

Co-authored-by: undefined <undefined>
Tnon 3 years ago
parent
commit
f61cc2dcef

+ 2 - 2
src/packages/__VUE/table/common.ts

@@ -69,8 +69,8 @@ export const component = (componentName: string, translate: Function) => {
       };
 
       const sortDataItem = () => {
-        return props.columns.map((value: any) => {
-          return value.key;
+        return props.columns.map((columns: TableColumnProps) => {
+          return [columns.key, columns.render];
         });
       };
 

+ 12 - 1
src/packages/__VUE/table/demo.vue

@@ -50,7 +50,18 @@ export default createDemo({
         },
         {
           title: '性别',
-          key: 'sex'
+          key: 'sex',
+          render: ({ sex }) => {
+            return h(
+              'span',
+              {
+                style: {
+                  color: sex === '女' ? 'blue' : 'green'
+                }
+              },
+              sex
+            );
+          }
         },
         {
           title: '学历',

+ 298 - 287
src/packages/__VUE/table/doc.md

@@ -6,7 +6,7 @@
 
 ### 安装
 
-``` javascript
+```javascript
 import { createApp } from 'vue';
 // vue
 import { Table } from '@nutui/nutui';
@@ -32,42 +32,53 @@ app.use(Table);
   export default {
     props: {},
     setup() {
-        const state = reactive({
-            columns: [
-            {
-              title: '姓名',
-              key: 'name'
-            },
-            {
-              title: '性别',
-              key: 'sex'
-            },
-            {
-              title: '学历',
-              key: 'record'
-            }
-          ],
-          data: [
-            {
-              name: 'Tom',
-              sex: '男',
-              record: '小学'
-            },
-            {
-              name: 'Lucy',
-              sex: '女',
-              record: '本科'
-            },
-            {
-              name: 'Jack',
-              sex: '男',
-              record: '高中'
+      const state = reactive({
+        columns: [
+          {
+            title: '姓名',
+            key: 'name'
+          },
+          {
+            title: '性别',
+            key: 'sex',
+            render: (record) => {
+              return h(
+                'span',
+                {
+                  style: {
+                    color: record.sex === '女' ? 'blue' : 'green'
+                  }
+                },
+                record.sex
+              );
             }
-          ],
-        });
-        return {
-            ...toRefs(state),
-        };
+          },
+          {
+            title: '学历',
+            key: 'record'
+          }
+        ],
+        data: [
+          {
+            name: 'Tom',
+            sex: '男',
+            record: '小学'
+          },
+          {
+            name: 'Lucy',
+            sex: '女',
+            record: '本科'
+          },
+          {
+            name: 'Jack',
+            sex: '男',
+            record: '高中'
+          }
+        ]
+      });
+      return {
+        ...toRefs(state)
+      };
     }
   };
 </script>
@@ -88,44 +99,44 @@ app.use(Table);
   export default {
     props: {},
     setup() {
-        const state = reactive({
-            bordered: false,
-            columns: [
-            {
-              title: '姓名',
-              key: 'name',
-              align: 'center'
-            },
-            {
-              title: '性别',
-              key: 'sex'
-            },
-            {
-              title: '学历',
-              key: 'record'
-            }
-          ],
-          data: [
-            {
-              name: 'Tom',
-              sex: '男',
-              record: '小学'
-            },
-            {
-              name: 'Lucy',
-              sex: '女',
-              record: '本科'
-            },
-            {
-              name: 'Jack',
-              sex: '男',
-              record: '高中'
-            }
-          ],
-        });
-        return {
-            ...toRefs(state),
-        };
+      const state = reactive({
+        bordered: false,
+        columns: [
+          {
+            title: '姓名',
+            key: 'name',
+            align: 'center'
+          },
+          {
+            title: '性别',
+            key: 'sex'
+          },
+          {
+            title: '学历',
+            key: 'record'
+          }
+        ],
+        data: [
+          {
+            name: 'Tom',
+            sex: '男',
+            record: '小学'
+          },
+          {
+            name: 'Lucy',
+            sex: '女',
+            record: '本科'
+          },
+          {
+            name: 'Jack',
+            sex: '男',
+            record: '高中'
+          }
+        ]
+      });
+      return {
+        ...toRefs(state)
+      };
     }
   };
 </script>
@@ -146,62 +157,62 @@ app.use(Table);
   export default {
     props: {},
     setup() {
-        const state = reactive({
-            columns: [
-            {
-              title: '姓名',
-              key: 'name'
-            },
-            {
-              title: '性别',
-              key: 'sex'
-            },
-            {
-              title: '学历',
-              key: 'record'
-            },
-            {
-              title: '年龄',
-              key: 'age'
-            },
-            {
-              title: '地址',
-              key: 'address'
-            }
-          ],
-          data: [
-            {
-              name: 'Tom',
-              sex: '男',
-              record: '小学',
-              age: 13,
-              address: '北京'
-            },
-            {
-              name: 'Lucy',
-              sex: '女',
-              record: '本科',
-              age: 34,
-              address: '上海'
-            },
-            {
-              name: 'Jack',
-              sex: '男',
-              record: '高中',
-              age: 4,
-              address: '杭州'
-            }
-          ],
-          summary: () => {
-            return {
-              value: '这是总结栏',
-              colspan: 5
-            }
+      const state = reactive({
+        columns: [
+          {
+            title: '姓名',
+            key: 'name'
+          },
+          {
+            title: '性别',
+            key: 'sex'
+          },
+          {
+            title: '学历',
+            key: 'record'
+          },
+          {
+            title: '年龄',
+            key: 'age'
+          },
+          {
+            title: '地址',
+            key: 'address'
+          }
+        ],
+        data: [
+          {
+            name: 'Tom',
+            sex: '男',
+            record: '小学',
+            age: 13,
+            address: '北京'
+          },
+          {
+            name: 'Lucy',
+            sex: '女',
+            record: '本科',
+            age: 34,
+            address: '上海'
+          },
+          {
+            name: 'Jack',
+            sex: '男',
+            record: '高中',
+            age: 4,
+            address: '杭州'
           }
-        });
-        return {
-            ...toRefs(state),
-        };
+        ],
+        summary: () => {
+          return {
+            value: '这是总结栏',
+            colspan: 5
+          };
+        }
+      });
+      return {
+        ...toRefs(state)
+      };
     }
   };
 </script>
@@ -222,57 +233,57 @@ app.use(Table);
   export default {
     props: {},
     setup() {
-        const state = reactive({
-          striped: true,
-          columns3: [
-            {
-              title: '姓名',
-              key: 'name'
-            },
-            {
-              title: '性别',
-              key: 'sex'
-            },
-            {
-              title: '学历',
-              key: 'record'
-            },
-            {
-              title: '年龄',
-              key: 'age'
-            },
-            {
-              title: '地址',
-              key: 'address'
-            }
-          ],
-          data2: [
-            {
-              name: 'Tom',
-              sex: '男',
-              record: '小学',
-              age: 13,
-              address: '北京'
-            },
-            {
-              name: 'Lucy',
-              sex: '女',
-              record: '本科',
-              age: 34,
-              address: '上海'
-            },
-            {
-              name: 'Jack',
-              sex: '男',
-              record: '高中',
-              age: 4,
-              address: '杭州'
-            }
-          ]
-        });
-        return {
-            ...toRefs(state),
-        };
+      const state = reactive({
+        striped: true,
+        columns3: [
+          {
+            title: '姓名',
+            key: 'name'
+          },
+          {
+            title: '性别',
+            key: 'sex'
+          },
+          {
+            title: '学历',
+            key: 'record'
+          },
+          {
+            title: '年龄',
+            key: 'age'
+          },
+          {
+            title: '地址',
+            key: 'address'
+          }
+        ],
+        data2: [
+          {
+            name: 'Tom',
+            sex: '男',
+            record: '小学',
+            age: 13,
+            address: '北京'
+          },
+          {
+            name: 'Lucy',
+            sex: '女',
+            record: '本科',
+            age: 34,
+            address: '上海'
+          },
+          {
+            name: 'Jack',
+            sex: '男',
+            record: '高中',
+            age: 4,
+            address: '杭州'
+          }
+        ]
+      });
+      return {
+        ...toRefs(state)
+      };
     }
   };
 </script>
@@ -288,11 +299,9 @@ app.use(Table);
 <template>
   <nut-table :columns="columns" :data="data"></nut-table>
   <nut-table :columns="columns3" :data="data3">
-      <template #nodata>
-      <div class="no-data">
-          这里是自定义展示
-      </div>
-      </template>
+    <template #nodata>
+      <div class="no-data"> 这里是自定义展示 </div>
+    </template>
   </nut-table>
 </template>
 <script lang="ts">
@@ -345,13 +354,13 @@ app.use(Table);
             key: 'address'
           }
         ],
-        data3: [],
+        data3: []
       });
       return {
-          ...toRefs(state),
+        ...toRefs(state)
       };
     }
-  }
+  };
 </script>
 ```
 
@@ -370,78 +379,78 @@ app.use(Table);
   import { Button, Icon } from '@nutui/nutui';
   export default {
     setup() {
-        const state = reactive({
-          columns: [
-            {
-              title: '姓名',
-              key: 'name',
-              align: 'center'
-            },
-            {
-              title: '性别',
-              key: 'sex'
-            },
-            {
-              title: '学历',
-              key: 'record'
-            },
-            {
-              title: '操作',
-              key: 'render'
-            }
-          ],
-          data: [
-              {
-              name: 'Tom',
-              sex: '男',
-              record: '小学',
-              render: () => {
-                return h(
-                  Button,
-                  {
-                    onClick: () => {
-                      (Toast as any).text('hello');
-                    },
-                    size: 'small',
-                    type: 'primary'
-                  },
-                  'Hello'
-                );
-              }
-            },
-            {
-              name: 'Lucy',
-              sex: '女',
-              record: '本科',
-              render: () => {
-                return h(Icon, { name: 'dongdong', size: '14px' });
-              }
-            },
-            {
-              name: 'Jack',
-              sex: '男',
-              record: '高中',
-              render: () => {
-                return h(
-                  Button,
-                  {
-                    type: 'success',
-                    size: 'small',
-                    onClick: () => {
-                      window.open('https://www.jd.com');
-                    }
+      const state = reactive({
+        columns: [
+          {
+            title: '姓名',
+            key: 'name',
+            align: 'center'
+          },
+          {
+            title: '性别',
+            key: 'sex'
+          },
+          {
+            title: '学历',
+            key: 'record'
+          },
+          {
+            title: '操作',
+            key: 'render'
+          }
+        ],
+        data: [
+          {
+            name: 'Tom',
+            sex: '男',
+            record: '小学',
+            render: () => {
+              return h(
+                Button,
+                {
+                  onClick: () => {
+                    (Toast as any).text('hello');
                   },
-                  '跳转到京东'
-                );
-              }
+                  size: 'small',
+                  type: 'primary'
+                },
+                'Hello'
+              );
             }
-          ]
-        });
-        return {
-            ...toRefs(state),
-        };
+          },
+          {
+            name: 'Lucy',
+            sex: '女',
+            record: '本科',
+            render: () => {
+              return h(Icon, { name: 'dongdong', size: '14px' });
+            }
+          },
+          {
+            name: 'Jack',
+            sex: '男',
+            record: '高中',
+            render: () => {
+              return h(
+                Button,
+                {
+                  type: 'success',
+                  size: 'small',
+                  onClick: () => {
+                    window.open('https://www.jd.com');
+                  }
+                },
+                '跳转到京东'
+              );
+            }
+          }
+        ]
+      });
+      return {
+        ...toRefs(state)
+      };
     }
-  }
+  };
 </script>
 ```
 
@@ -510,15 +519,15 @@ app.use(Table);
         ]
       });
       onMounted(() => {
-          setTimeout(() => {
-              state.data = state.data1.slice();
-          }, 5000);
+        setTimeout(() => {
+          state.data = state.data1.slice();
+        }, 5000);
       });
       return {
-          ...toRefs(state),
+        ...toRefs(state)
       };
     }
-  }
+  };
 </script>
 ```
 
@@ -547,7 +556,7 @@ app.use(Table);
           },
           {
             title: '性别',
-            key: 'sex',
+            key: 'sex'
           },
           {
             title: '学历',
@@ -556,7 +565,9 @@ app.use(Table);
           {
             title: '年龄',
             key: 'age',
-            sorter: (row1: any, row2: any) => { return row1.age - row2.age }
+            sorter: (row1: any, row2: any) => {
+              return row1.age - row2.age;
+            }
           }
         ],
         data: [
@@ -580,17 +591,17 @@ app.use(Table);
           }
         ]
       });
-      
+
       const handleSorter = (item: TableColumnProps) => {
         (Toast as any).text(`${JSON.stringify(item)}`);
-      }
+      };
 
       return {
-          ...toRefs(state),
-          handleSorter
+        ...toRefs(state),
+        handleSorter
       };
-  }
-  }
+    }
+  };
 </script>
 ```
 
@@ -600,26 +611,26 @@ app.use(Table);
 
 ### Props
 
-| 参数         | 说明                             | 类型   | 默认值           |
-|--------------|----------------------------------|--------|------------------|
-| bordered         | 是否显示边框 | Boolean |`true`         |
-| columns         | 表头数据 | TableColumnProps[] |`[]`         |
-| data         | 表格数据 | Object[] |`[]`         |
-| summary         | 是否显示简介 | Function | -         |
-| striped         | 条纹是否明暗交替 | Boolean |`false` |
+| 参数     | 说明             | 类型               | 默认值  |
+| -------- | ---------------- | ------------------ | ------- |
+| bordered | 是否显示边框     | Boolean            | `true`  |
+| columns  | 表头数据         | TableColumnProps[] | `[]`    |
+| data     | 表格数据         | Object[]           | `[]`    |
+| summary  | 是否显示简介     | Function           | -       |
+| striped  | 条纹是否明暗交替 | Boolean            | `false` |
 
 ### TableColumnProps
 
-| 参数         | 说明                             | 类型   | 默认值           |
-|--------------|----------------------------------|--------|------------------|
-| key         | 列的唯一标识 | String |``  |
-| title         | 表头标题 | String |``         |
-| align         | 列的对齐方式,可选值`left`,`center`,`right` | String |`left`         |
-| sorter         | 排序,可选值有 `true`,`function`, `default`, 其中 `default`表示点击之后可能会依赖接口, `function`可以返回具体的排序函数, `default`表示采用默认的排序算法 | Boolean、Function、String |-|
+| 参数   | 说明                                                                                                                                                     | 类型                      | 默认值 |
+| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ------ |
+| key    | 列的唯一标识                                                                                                                                             | String                    | ``     |
+| title  | 表头标题                                                                                                                                                 | String                    | ``     |
+| align  | 列的对齐方式,可选值`left`,`center`,`right`                                                                                                              | String                    | `left` |
+| sorter | 排序,可选值有 `true`,`function`, `default`, 其中 `default`表示点击之后可能会依赖接口, `function`可以返回具体的排序函数, `default`表示采用默认的排序算法 | Boolean、Function、String | -      |
+| render | 自定义渲染列数据,优先级高                                                                                                                               | Function(record)          | -      |
 
 ### Events
 
-| 事件名 | 说明           | 回调参数     |
-|--------|----------------|--------------|
-| sorter  | 点击排序按钮触发 | item: 当前点击的表头的数据 |
-
+| 事件名 | 说明             | 回调参数                   |
+| ------ | ---------------- | -------------------------- |
+| sorter | 点击排序按钮触发 | item: 当前点击的表头的数据 |

+ 9 - 3
src/packages/__VUE/table/index.taro.vue

@@ -21,11 +21,17 @@
           <span
             class="nut-table__main__body__tr__td"
             :class="cellClasses(getColumnItem(value))"
-            v-for="value in sortDataItem()"
+            v-for="[value, render] in sortDataItem()"
             :key="value"
           >
-            <RenderColumn :slots="item[value]" v-if="typeof item[value] === 'function'"></RenderColumn>
-            <view v-else> {{ item[value] }} </view>
+            <RenderColumn
+              :slots="[render, item[value]]"
+              :record="item"
+              v-if="typeof item[value] === 'function' || typeof render === 'function'"
+            ></RenderColumn>
+            <view v-else>
+              {{ item[value] }}
+            </view>
           </span>
         </view>
       </view>

+ 9 - 3
src/packages/__VUE/table/index.vue

@@ -21,11 +21,17 @@
           <span
             class="nut-table__main__body__tr__td"
             :class="cellClasses(getColumnItem(value))"
-            v-for="value in sortDataItem()"
+            v-for="[value, render] in sortDataItem()"
             :key="value"
           >
-            {{ typeof item[value] !== 'function' ? item[value] : '' }}
-            <RenderColumn :slots="item[value]" v-if="typeof item[value] === 'function'"></RenderColumn>
+            <RenderColumn
+              :slots="[render, item[value]]"
+              :record="item"
+              v-if="typeof item[value] === 'function' || typeof render === 'function'"
+            ></RenderColumn>
+            <view v-else>
+              {{ item[value] }}
+            </view>
           </span>
         </view>
       </view>

+ 4 - 3
src/packages/__VUE/table/renderColumn.ts

@@ -1,9 +1,10 @@
-import { h } from 'vue';
+import { h, PropType } from 'vue';
 export default {
   setup(props: any) {
-    return () => h(`view`, {}, props.slots());
+    return () => h(`view`, {}, props.slots[0] ? props.slots[0](props.record) : props.slots[1](props.record));
   },
   props: {
-    slots: Function
+    slots: Array as PropType<Array<Function | undefined>>,
+    record: Object
   }
 };

+ 2 - 2
src/packages/__VUE/table/types.ts

@@ -1,10 +1,10 @@
-import { VNodeChild } from 'vue';
+import { VNode, VNodeChild } from 'vue';
 export interface TableColumnProps {
   key?: string;
   title?: string;
   align?: string;
   sorter?: Function;
-  render?: (rowData: object, rowIndex: number) => VNodeChild | string;
+  render?: (rowData?: object, rowIndex?: number) => VNodeChild | string | VNode;
 }
 
 export interface TableProps {