Browse Source

component - new powerful dynamic-table

hare8999@163.com 3 năm trước cách đây
mục cha
commit
29d3386357

+ 59 - 0
src/components/dynamic-table/demo.vue

@@ -0,0 +1,59 @@
+<template>
+  <dynamic-table :rows="rows" :columns="columns">
+    <template #privacy="{display}">
+      <span style="color: red">*</span>{{ display }}
+    </template>
+    <template #rank="{display}">
+      <span style="color: red">{{ display }}</span>
+    </template>
+  </dynamic-table>
+</template>
+
+<script>
+export default {
+  name: 'demo',
+  data() {
+    return {
+      rows: [{
+        id: 1,
+        name: '张三',
+        age: 12,
+        score: 558,
+        rank: 3
+      }, {
+        id: 2,
+        name: '李四',
+        age: 15,
+        score: 624,
+        rank: 1
+      }, {
+        id: 3,
+        name: '王五',
+        age: 12,
+        score: 599,
+        rank: 2
+      }],
+      columns: [
+        {
+          prop: 'info', label: '基本信息', align: 'left', children: [
+            { prop: 'check', label: '', type: 'selection' },
+            { prop: 'id', label: 'ID' },
+            { prop: 'name', label: '姓名' },
+            { prop: 'age', label: '年龄' },
+            {
+              prop: 'privacy', label: '隐私', slotHeader: 'privacy', children: [
+                { prop: 'score', label: '分数' },
+                { prop: 'rank', label: '排名', slotBody: 'rank' }
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 44 - 0
src/components/dynamic-table/dynamic-table-column.vue

@@ -0,0 +1,44 @@
+<template>
+  <el-table-column v-bind="mergedColumnAttrs">
+    <template v-if="column.slotHeader" #header="headerScope">
+      <slot :name="column.slotHeader" v-bind="{ ...headerScope, columnDef: column, display: column.label}">
+        {{ column.label }}
+      </slot>
+    </template>
+    <template v-if="column.slotBody" #default="scope">
+      <slot :name="column.slotBody" v-bind="{...scope, columnDef: column, display: scope.row[column.prop]}">
+        {{ scope.row[column.prop] }}
+      </slot>
+    </template>
+    <dynamic-table-column v-for="child in visibleChildren" :key="child.prop" :column="child"
+                          :default-setting="defaultSetting">
+      <template v-for="slot in Object.keys($scopedSlots)" #[slot]="scope">
+        <slot :name="slot" v-bind="scope">
+          {{ scope.display }}
+        </slot>
+      </template>
+    </dynamic-table-column>
+  </el-table-column>
+</template>
+
+<script>
+export default {
+  name: 'dynamic-table-column',
+  props: {
+    column: { type: Object, default: () => ({ prop: '', slotBody: '', slotHeader: '', children: [] }) },
+    defaultSetting: { type: Object, default: () => ({}) }
+  },
+  computed: {
+    mergedColumnAttrs() {
+      return { ...this.defaultSetting, ...this.column }
+    },
+    visibleChildren() {
+      return this.column.children?.filter(child => child.hidden !== true) || []
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 21 - 12
src/components/dynamic-table/index.vue

@@ -1,27 +1,36 @@
 <template>
-  <el-table ref="table" v-bind="$attrs" v-on="$listeners">
-    <el-table-column v-for="(column,idx) in visibleColumns" :key="idx" v-bind="col">
-      <template v-if="column.slotHeader" #header="{$index}">
-        <slot :name="column.slotHeader" v-bind="{ column, $index}">
-          {{ column.label }}
+  <el-table ref="table" :data="rows" v-bind="mergedAttrs" v-on="$listeners">
+    <dynamic-table-column v-for="column in visibleColumns" :key="column.prop" :column="column"
+                          :default-setting="columnDefaultSetting">
+      <template v-for="slot in Object.keys($scopedSlots)" #[slot]="scope">
+        <slot :name="slot" v-bind="scope">
+          {{ scope.display }}
         </slot>
       </template>
-      <template v-if="column.slotBody" #default="{row, $index}">
-        <slot :name="column.slotBody" v-bind="{row, column, $index, value: row[column.prop]}">
-          {{ row[column.prop] }}
-        </slot>
-      </template>
-    </el-table-column>
+    </dynamic-table-column>
   </el-table>
 </template>
 
 <script>
+/*
+* NOTE:22.5.9 hht
+* 新的动态表格,支持多级嵌套与动态属性/事件
+* */
+import DynamicTableColumn from '@/components/dynamic-table/dynamic-table-column'
+
 export default {
   name: 'dynamic-table',
+  components: { DynamicTableColumn },
   props: {
-    columns: { type: Array, default: () => [{ prop: '', slotBody: '', slotHeader: '' }] }
+    rows: { type: Array, default: () => [] },
+    columns: { type: Array, default: () => [] },
+    tableDefaultSetting: { type: Object, default: () => ({}) },
+    columnDefaultSetting: { type: Object, default: () => ({ align: 'center' }) }
   },
   computed: {
+    mergedAttrs() {
+      return { ...this.tableDefaultSetting, ...this.$attrs }
+    },
     visibleColumns() {
       return this.columns.filter(col => col.hidden !== true)
     },