antdv

字数 3019 · 2021-02-02

RangePicker

index.js:

1
{ RangePicker: wrapPicker(RangePicker, RangePickerProps(), 'date'), }

wrapPicker.js:

1
2
3
4
5
6
7
8
render() {
  return (
    <LocaleReceiver
      componentName="DatePicker"
      defaultLocale={this.getDefaultLocale}
      scopedSlots={ default: this.renderPicker }
    />
  );

LocaleReceiver.jsx:

1
2
3
4
5
6
render() {
  const { $scopedSlots } = this;
  const children = this.children || $scopedSlots.default; // $scopedSlots.default
  const { antLocale } = this.localeData;
  return children(this.getLocale(), this.getLocaleCode(), antLocale);
},

wrapPicker.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
wrapPicker(Picker, props, pickerType) { // Picker = RangePicker
  renderPicker(locale, localeCode) {
    const props = getOptionProps(this);
    const pickerProps = {
      ...props,
    }
    // ...
    return (
    <Picker {...pickerProps}>
      {this.$slots &&
        Object.keys(this.$slots).map(key => (
          <template slot={key} key={key}>
            {this.$slots[key]}
          </template>
        ))}
    </Picker>
    );
  }
}

RangePicker.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import VcDatePicker from '../vc-calendar/src/Picker';
// ...
render() {
  const calendar = <RangeCalendar {...rangeCalendarProps} />;
  const input = ({ value: inputValue }) => {
    return (<span>...</span>)
  };
  const vcDatePickerProps = mergeProps(
    // ...
    {
      props: {
        calendar
      },
      scopedSlots: { default: input, ...$scopedSlots },
    }
  );
  return (
    <span>
      <VcDatePicker {...vcDatePickerProps} />
    </span>
  );
}

Picker.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
getCalendarElement() {
  const props = this.$props;
  return cloneElement(props.calendar, extraProps);
}
render() {
  const children = this.$scopedSlots.default;
  this.calendarInstance = this.getCalendarElement();
  return (
    <Trigger
      // ...
    >
      <template slot="popup">{this.calendarInstance}</template>
      {cloneElement(children(childrenState, props), { on: { keydown: this.onKeyDown } })}
    </Trigger>
  )
}

RangeCalendar.jsx:

1
// ...

Table

components/table/index.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
import T from './Table';

const Table = {
  render() {
    // ...
    return <T {...tProps} />;
  }
}

Table.install = function(Vue) {
  // ...
  Vue.component(Table.name, Table);
};

components/table/Table.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import VcTable from '../vc-table';

const createComponents = (components = {}) => {
  const bodyRow = components?.body?.row;
  return {
    ...components,
    body: {
      ...components.body,
      row: createBodyRow(bodyRow),
    },
  };
};

export default {
  data() {
    return {
      sComponents: createComponents(this.components/* undefined */),
    }
  },
  methods: {
    renderTable(){
      const vcTableProps = {
        components: this.sComponents,
      };
      return <VcTable {...vcTableProps} />;
    }
  },
  render() {
    const table = (
      <LocaleReceiver children={this.renderTable()}/>
    );
    <Spin>
      {this.renderPagination('top')}
      {table}
      {this.renderPagination('bottom')}
    </Spin>
  }
}

components/vc-table/index.js:

1
2
3
4
5
6
7
import T from './src/Table';
const Table = {
  render() {
    return <T {...tProps} />;
  }
};
export default Table;

components/vc-table/src/Table.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import HeadTable from './HeadTable';
import BodyTable from './BodyTable';

export default {
  props: initDefaultProps(
    components: PropTypes.shape({
      // ...
    }),
  ),
  data() {
    return {
      sComponents: merge(
        {
          table: 'table',
          header: {
            wrapper: 'thead',
            row: 'tr',
            cell: 'th',
          },
          body: {
            wrapper: 'tbody',
            row: 'tr',
            cell: 'td',
          },
        },
        this.components,
      ),
    }
  },
  provide() {
    return {
      table: this,
    };
  },
  methods: {
    renderTable(options) {
      const headTable = (
        <HeadTable/>
      );
      const bodyTable = (
        <BodyTable/>
      );
      return [headTable, bodyTable];
    },
    renderMainTable() {
      const { scroll, prefixCls } = this;
      const table = [
        this.renderTable({
          columns: this.columnManager.groupedColumns(),
          isAnyColumnsFixed,
        }),
        this.renderEmptyText(),
        this.renderFooter(),
      ];
      return scrollable ? <div class={`${prefixCls}-scroll`}>{table}</div> : table;
    }
  },
  render() {
    const expandableTableProps = {
      scopedSlots: {
        default: expander => {
          return (
            <div>
              {this.rendetTitle()}
              <div>
                {this.renderMainTable()}
                {hasLeftFixed && this.renderLeftFixedTable()}
                {hasRightFixed && this.renderRightFixedTable()}
              </div>
            </div>
          );
        }
      }
    };
    return (
      <Provider store={this.store}>
        <ExpandableTable {...expandableTableProps} />
      </Provider>
    );
  }
}

components/vc-table/src/ExpandableTable.jsx:

1
2
3
4
5
6
7
8
9
const ExpandableTable = {
  render() {
    return (
      $scopedSlots.default &&
      $scopedSlots.default({/* params */})
    )
  }
}
export default connect()(ExpandableTable);

components/vc-table/src/BodyTable.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
export default {
  render() {
    const baseTable = (
      <BaseTable hasBody/>
    );
    return (
      <div>
        {baseTable}
      </div>
    );
  }
};

components/vc-table/src/BaseTable.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import TableHeader from './TableHeader';

const BaseTable = {
  inject: {
    table: { default: () => ({}) },
  },
  render() {
    const { components } = this.table;
    const Table = hasBody ? components.table : 'table';
    
    const BodyWrapper = components.body.wrapper;

    let body;
    if (hasBody) {
      body = (
        <BodyWrapper class={`${prefixCls}-tbody`}>
          {this.renderRows(data, 0)}
        </BodyWrapper>
      );
      if (getBodyWrapper) {
        body = getBodyWrapper(body);
      }
    }

    return (
      <Table>
        <ColGroup/>
        {hasHead && <TableHeader/>}
        {body}
      </Table>
    );
  }
};
export default connect()(BaseTable);

components/vc-table/src/HeadTable.jsx:

1
2
3
4
5
6
7
8
9
export default {
  render() {
    return (
      <div>
        <BaseTable hasBody={false}/>
      </div>
    );
  }
}

components/vc-table/src/TableHeader.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import TableHeaderRow from './TableHeaderRow';

export default {
  render() {
    const { sComponents: components } = this.table;
    const rows = getHeaderRows({ columns });
    <HeaderWrapper>
      {rows.map((row, index) => (
        <TableHeaderRow
          rows={rows}
          row={row}
          components={components}
        />
      ))}
    </HeaderWrapper>
  },
};

components/vc-table/src/TableHeaderRow.jsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const TableHeaderRow = {
  render(h) {
    const { row } = this;
    const HeaderRow = components.header.row;
    const HeaderCell = components.header.cell;
    return (
      <HeaderRow {...rowProps} style={style}>
        {row.map((cell, i) => {
          const { children } = cell;
          if (typeof HeaderCell === 'function') {
            return HeaderCell(h, headerCellProps, children);
          }
          return <HeaderCell {...headerCellProps}>{children}</HeaderCell>;
        })}
      </HeaderRow>
    );
  },
};
export default connect(/* params */})(TableHeaderRow);

Form

index.ts

1
2
3
4
5
6
7
8
9
10
import Form from './Form';

Form.install = function(Vue) {
  // ...
  Vue.component(Form.name, Form);
  Vue.component(Form.Item.name, Form.Item);
  Vue.prototype.$form = Form;
};

export default Form;

Form.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const Form = {

  create: (options = {}) => {
    return createDOMForm({
      fieldNameProp: 'id',
      ...options,
      fieldMetaProp: FIELD_META_PROP, // data-__meta
      fieldDataProp: FIELD_DATA_PROP, // data-__field
    });
  },

  createForm(context, options = {}) {
    const V = Base.Vue || Vue;
    return new V(Form.create({ ...options, templateContext: context })/* argumentContainer */());
  }

  provide() {
    FormContext: this,
    collectFormItemContext: this.form // ...
  }

  render() {
    return (<form>{$slots.default}</form>)
  }
}

export default Form;

createDomForm.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const mixin = {
  methods: {
    getForm() { /* ... */ }
    validateFieldsAndScroll() { /* ... */ }
  }
}
function createDOMForm(option) {
  return createBaseForm(
    {
      ...option,
    },
    [mixin],
  );
}

export default createDOMForm;

createBaseForm.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function createBaseForm(option = {}, mixins = []) {
  // ...

  return function decorate(WrappedComponent) {
    // ...
    const Form = {
      // ...
      methods: {
        validateFields() {
          const pending = new Promise();
          return pending;
        }
      }
    };
    return argumentContainer(Form, WrappedComponent);
  }
}

export default createBaseForm;