Commit a57cd44f3750f26174ed13ca044d55e5ec877441

Authored by liuhanchen
1 parent 98832d95

feat: 优化虚拟节点渲染

packages/schema-page/index.vue
... ... @@ -36,9 +36,15 @@
36 36 </slot>
37 37 </div>
38 38 <!-- 表格内容 -->
39   - <div v-if="schema.table || $scopedSlots.table" class="z-schema-page__table" v-loading="schema.loading !== false ? tableLoading : false">
  39 + <div v-if="schema.table || $scopedSlots.table" class="z-schema-page__table">
40 40 <slot name="table" v-bind="_slotScope">
41   - <z-schema-table :size="_size" :schema="tableSchemaDefaultProps(schema.table)" :data="tableData" @selection-change="onTableSelectionChange">
  41 + <z-schema-table
  42 + v-loading="schema.loading !== false ? tableLoading : false"
  43 + :size="_size"
  44 + :schema="tableSchemaDefaultProps(schema.table)"
  45 + :data="tableData"
  46 + @selection-change="onTableSelectionChange"
  47 + >
42 48 <template #prepend>
43 49 <slot name="table-prepend">
44 50 <el-table-column v-if="schema.selection !== false" type="selection" width="40" align="center"></el-table-column>
... ...
packages/table/normal.vue
1 1 <script>
2 2 import { get } from '../utils';
  3 +import { renderContext } from '../utils/vnode';
3 4  
4 5 // 标题渲染
5 6 function headerRender(h, context, item) {
... ... @@ -63,11 +64,15 @@ export default {
63 64 const elTableColumns = createElTableColumns(h, context, columns);
64 65 // 前置插槽
65 66 const prependSlot = scopedSlots.prepend ? scopedSlots.prepend() : '';
  67 + // 左侧插槽
  68 + const leftSlot = scopedSlots.left ? scopedSlots.left() : '';
  69 + // 右侧插槽
  70 + const rightSlot = scopedSlots.right ? scopedSlots.right() : '';
66 71 // 后置插槽
67 72 const appendSlot = scopedSlots.append ? scopedSlots.append() : '';
68 73 // 渲染组件时移除当前组件特有的props,避免透传不必要的参数
69 74 delete context.columns;
70   - return h('el-table', context, [prependSlot, ...elTableColumns, appendSlot]);
  75 + return h('el-table', renderContext(context), [prependSlot, leftSlot, ...elTableColumns, rightSlot, appendSlot]);
71 76 },
72 77 };
73 78 </script>
... ...
packages/utils/vnode.js
... ... @@ -16,7 +16,40 @@ export function registerRef(vnode, context) {
16 16  
17 17 // 简写注册ref
18 18 export function ref(name, context) {
19   - return registerRef(context._c(name, context), context);
  19 + const vnode = context._c(name, renderContext(context));
  20 + return registerRef(vnode, context);
  21 +}
  22 +
  23 +// 清除attrs上的数组和对象,仅用props传递
  24 +function clearAttrs(attrs) {
  25 + const newAttrs = Object.assign({}, attrs);
  26 + Object.keys(newAttrs).forEach(key => {
  27 + if (typeof newAttrs[key] === 'function' || typeof newAttrs[key] === 'object') {
  28 + delete newAttrs[key];
  29 + }
  30 + });
  31 + delete newAttrs.slot;
  32 + return newAttrs;
  33 +}
  34 +
  35 +// 渲染函数式组件context
  36 +export function renderContext(context) {
  37 + const result = {
  38 + staticClass: context.data.staticClass,
  39 + class: context.data.class,
  40 + staticStyle: context.data.staticStyle,
  41 + style: context.data.style,
  42 + attrs: clearAttrs(context.data.attrs),
  43 + props: context.props,
  44 + on: context.listeners,
  45 + directives: context.data.directives,
  46 + scopedSlots: context.scopedSlots,
  47 + slot: context.data.slot,
  48 + key: context.data.key,
  49 + ref: context.data.ref,
  50 + refInFor: true,
  51 + };
  52 + return result;
20 53 }
21 54  
22 55 export default {
... ...