component.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { basic } from '../mixins/basic';
  2. const relationFunctions = {
  3. ancestor: {
  4. linked(parent) {
  5. // @ts-ignore
  6. this.parent = parent;
  7. },
  8. unlinked() {
  9. // @ts-ignore
  10. this.parent = null;
  11. },
  12. },
  13. descendant: {
  14. linked(child) {
  15. // @ts-ignore
  16. this.children = this.children || [];
  17. // @ts-ignore
  18. this.children.push(child);
  19. },
  20. unlinked(child) {
  21. // @ts-ignore
  22. this.children = (this.children || []).filter((it) => it !== child);
  23. },
  24. },
  25. };
  26. function mapKeys(source, target, map) {
  27. Object.keys(map).forEach((key) => {
  28. if (source[key]) {
  29. target[map[key]] = source[key];
  30. }
  31. });
  32. }
  33. function makeRelation(options, vantOptions, relation) {
  34. const { type, name, linked, unlinked, linkChanged } = relation;
  35. const { beforeCreate, destroyed } = vantOptions;
  36. if (type === 'descendant') {
  37. options.created = function () {
  38. beforeCreate && beforeCreate.bind(this)();
  39. this.children = this.children || [];
  40. };
  41. options.detached = function () {
  42. this.children = [];
  43. destroyed && destroyed.bind(this)();
  44. };
  45. }
  46. options.relations = Object.assign(options.relations || {}, {
  47. [`../${name}/index`]: {
  48. type,
  49. linked(node) {
  50. relationFunctions[type].linked.bind(this)(node);
  51. linked && linked.bind(this)(node);
  52. },
  53. linkChanged(node) {
  54. linkChanged && linkChanged.bind(this)(node);
  55. },
  56. unlinked(node) {
  57. relationFunctions[type].unlinked.bind(this)(node);
  58. unlinked && unlinked.bind(this)(node);
  59. },
  60. },
  61. });
  62. }
  63. function VantComponent(vantOptions = {}) {
  64. const options = {};
  65. mapKeys(vantOptions, options, {
  66. data: 'data',
  67. props: 'properties',
  68. mixins: 'behaviors',
  69. methods: 'methods',
  70. beforeCreate: 'created',
  71. created: 'attached',
  72. mounted: 'ready',
  73. relations: 'relations',
  74. destroyed: 'detached',
  75. classes: 'externalClasses',
  76. });
  77. const { relation } = vantOptions;
  78. if (relation) {
  79. makeRelation(options, vantOptions, relation);
  80. }
  81. // add default externalClasses
  82. options.externalClasses = options.externalClasses || [];
  83. options.externalClasses.push('custom-class');
  84. // add default behaviors
  85. options.behaviors = options.behaviors || [];
  86. options.behaviors.push(basic);
  87. // map field to form-field behavior
  88. if (vantOptions.field) {
  89. options.behaviors.push('wx://form-field');
  90. }
  91. if (options.properties) {
  92. Object.keys(options.properties).forEach((name) => {
  93. if (Array.isArray(options.properties[name])) {
  94. // miniprogram do not allow multi type
  95. options.properties[name] = null;
  96. }
  97. });
  98. }
  99. // add default options
  100. options.options = {
  101. multipleSlots: true,
  102. addGlobalClass: true,
  103. };
  104. Component(options);
  105. }
  106. export { VantComponent };