transformComponent.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.rewritePropsBinding = exports.isPropsBinding = exports.rewriteBinding = exports.transformComponent = void 0;
  4. const shared_1 = require("@vue/shared");
  5. const compiler_core_1 = require("@vue/compiler-core");
  6. const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
  7. const transform_1 = require("../transform");
  8. const utils_1 = require("./utils");
  9. const codegen_1 = require("../codegen");
  10. const types_1 = require("@babel/types");
  11. const runtimeHelpers_1 = require("../runtimeHelpers");
  12. const ast_1 = require("../ast");
  13. const vIf_1 = require("./vIf");
  14. const transformComponent = (node, context) => {
  15. if (!(0, uni_cli_shared_1.isUserComponent)(node, context)) {
  16. return;
  17. }
  18. addComponentType(node, context);
  19. addVueId(node, context);
  20. processBooleanAttr(node);
  21. return function postTransformComponent() {
  22. context.vueIds.pop();
  23. };
  24. };
  25. exports.transformComponent = transformComponent;
  26. function addComponentType(node, context) {
  27. if (!context.isMiniProgramComponent(node.tag)) {
  28. return;
  29. }
  30. node.props.push((0, uni_cli_shared_1.createAttributeNode)(utils_1.ATTR_COM_TYPE, 'm'));
  31. }
  32. function addVueId(node, context) {
  33. let { hashId, scopes, currentScope, currentVueId } = context;
  34. if (!hashId) {
  35. return;
  36. }
  37. let vueId = hashId + '-' + scopes.vueId++;
  38. const indexs = [];
  39. while (currentScope) {
  40. if ((0, transform_1.isVForScope)(currentScope)) {
  41. indexs.push(`+'-'+${currentScope.indexAlias}`);
  42. }
  43. currentScope = currentScope.parent;
  44. }
  45. const inFor = !!indexs.length;
  46. if (inFor) {
  47. vueId = `'${vueId}'` + indexs.reverse().join('');
  48. }
  49. context.vueIds.push(vueId);
  50. let value = vueId;
  51. if (currentVueId) {
  52. const isParentDynamic = currentVueId.includes('+');
  53. const isCurrentDynamic = vueId.includes('+');
  54. if (isParentDynamic || isCurrentDynamic) {
  55. value = `(${vueId})+','+(${isParentDynamic ? currentVueId : `'${currentVueId}'`})`;
  56. }
  57. else {
  58. value = vueId + ',' + currentVueId;
  59. }
  60. }
  61. if (value.includes('+')) {
  62. return node.props.push((0, uni_cli_shared_1.createBindDirectiveNode)(utils_1.ATTR_VUE_ID, value));
  63. }
  64. return node.props.push((0, uni_cli_shared_1.createAttributeNode)(utils_1.ATTR_VUE_ID, value));
  65. }
  66. /**
  67. * <uni-collapse accordion/> => <uni-collapse :accordion="true"/>
  68. * 否则部分平台(快手)可能获取到的 accordion 是空字符串
  69. * @param param0
  70. */
  71. function processBooleanAttr({ props }) {
  72. props.forEach((prop, index) => {
  73. if (prop.type === 6 /* NodeTypes.ATTRIBUTE */ &&
  74. typeof prop.value === 'undefined') {
  75. props.splice(index, 1, (0, uni_cli_shared_1.createBindDirectiveNode)(prop.name, 'true'));
  76. }
  77. });
  78. }
  79. const builtInProps = [
  80. // 'id',
  81. 'class',
  82. 'style',
  83. utils_1.ATTR_VUE_ID,
  84. utils_1.ATTR_VUE_PROPS,
  85. utils_1.ATTR_VUE_SLOTS,
  86. utils_1.ATTR_VUE_REF,
  87. utils_1.ATTR_VUE_REF_IN_FOR,
  88. utils_1.ATTR_COM_TYPE,
  89. 'eO',
  90. 'e-o',
  91. 'onVI',
  92. 'ref',
  93. 'slot',
  94. 'key',
  95. 'is',
  96. ];
  97. function isComponentProp(name) {
  98. if (builtInProps.includes(name)) {
  99. return false;
  100. }
  101. if (name.startsWith('data-')) {
  102. return false;
  103. }
  104. return true;
  105. }
  106. /**
  107. * 重写组件 props 绑定
  108. * @param node
  109. * @param context
  110. */
  111. function rewriteBinding({ tag, props }, context) {
  112. const isMiniProgramComponent = context.isMiniProgramComponent(tag);
  113. if (isMiniProgramComponent === 'plugin' ||
  114. isMiniProgramComponent === 'dynamicLib' ||
  115. isMiniProgramComponent === 'ext') {
  116. // 因无法介入插件类型组件内部实现,故保留原始属性
  117. return;
  118. }
  119. const createObjectProperty = isMiniProgramComponent
  120. ? (name, value) => (0, types_1.objectProperty)((0, types_1.identifier)((0, shared_1.camelize)(name)), value)
  121. : (name, value) => {
  122. const computed = !(0, compiler_core_1.isSimpleIdentifier)(name);
  123. return (0, types_1.objectProperty)(computed ? (0, types_1.stringLiteral)(name) : (0, types_1.identifier)(name), value, computed);
  124. };
  125. const properties = [];
  126. for (let i = 0; i < props.length; i++) {
  127. const prop = props[i];
  128. let isIdProp = false;
  129. if ((0, uni_cli_shared_1.isAttributeNode)(prop)) {
  130. const { name } = prop;
  131. isIdProp = name === 'id';
  132. if (!isComponentProp(name)) {
  133. continue;
  134. }
  135. properties.push(createObjectProperty(name, (0, types_1.stringLiteral)(prop.value?.content || '')));
  136. }
  137. else if ((0, uni_cli_shared_1.isDirectiveNode)(prop)) {
  138. if (prop.name !== 'bind') {
  139. continue;
  140. }
  141. const { arg, exp } = prop;
  142. if (!exp) {
  143. continue;
  144. }
  145. if (!arg) {
  146. const spreadElement = createVBindSpreadElement(prop, context);
  147. if (spreadElement) {
  148. properties.push(spreadElement);
  149. }
  150. }
  151. else if ((0, compiler_core_1.isStaticExp)(arg)) {
  152. isIdProp = arg.content === 'id';
  153. if (!isComponentProp(arg.content)) {
  154. continue;
  155. }
  156. // :name="name"
  157. const valueExpr = (0, ast_1.parseExpr)((0, codegen_1.genExpr)(exp), context, exp);
  158. if (!valueExpr) {
  159. continue;
  160. }
  161. properties.push(createObjectProperty(arg.content, valueExpr));
  162. }
  163. else {
  164. // :[dynamic]="dynamic"
  165. const leftExpr = (0, ast_1.parseExpr)((0, codegen_1.genExpr)(arg), context, exp);
  166. if (!leftExpr) {
  167. continue;
  168. }
  169. const valueExpr = (0, ast_1.parseExpr)((0, codegen_1.genExpr)(exp), context, exp);
  170. if (!valueExpr) {
  171. continue;
  172. }
  173. properties.push((0, types_1.objectProperty)((0, types_1.logicalExpression)('||', leftExpr, (0, types_1.stringLiteral)('')), valueExpr, true));
  174. }
  175. }
  176. // 即保留 id 属性,又补充到 props 中
  177. if (!isIdProp) {
  178. props.splice(i, 1);
  179. i--;
  180. }
  181. }
  182. if (properties.length) {
  183. props.push((0, uni_cli_shared_1.createBindDirectiveNode)(utils_1.ATTR_VUE_PROPS, (0, codegen_1.genBabelExpr)((0, types_1.objectExpression)(properties))));
  184. }
  185. }
  186. exports.rewriteBinding = rewriteBinding;
  187. function createVBindSpreadElement(prop, context) {
  188. const { arg, exp } = prop;
  189. if (!exp) {
  190. return;
  191. }
  192. if (!arg) {
  193. const argument = (0, ast_1.parseExpr)((0, codegen_1.genExpr)(exp), context, exp);
  194. if (!argument) {
  195. return;
  196. }
  197. return (0, types_1.spreadElement)(argument);
  198. }
  199. }
  200. function isPropsBinding({ arg }) {
  201. return (arg &&
  202. arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
  203. arg.content === utils_1.ATTR_VUE_PROPS);
  204. }
  205. exports.isPropsBinding = isPropsBinding;
  206. function rewritePropsBinding(dir, node, context) {
  207. dir.exp = (0, compiler_core_1.createSimpleExpression)((0, codegen_1.genBabelExpr)((0, utils_1.rewirteWithHelper)(runtimeHelpers_1.RENDER_PROPS, (0, ast_1.parseExpr)(dir.exp, context), dir.loc, context)) + ((0, vIf_1.isIfElementNode)(node) && node.vIf.name === 'else' ? `||''` : ''));
  208. }
  209. exports.rewritePropsBinding = rewritePropsBinding;