足力健前端,vue版本

uni.compiler.js 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. const path = require('path')
  2. const t = require('@babel/types')
  3. function generateJsCode (properties = '{}') {
  4. return `
  5. wx.createComponent({
  6. generic:true,
  7. props: ${properties},
  8. render: function(){}
  9. })
  10. `
  11. }
  12. function hasOwn (obj, key) {
  13. return Object.prototype.hasOwnProperty.call(obj, key)
  14. }
  15. module.exports = {
  16. directive: 'wx:',
  17. createScopedSlots (slotName, props, state) {
  18. const componentName = 'scoped-slots-' + slotName
  19. if (!state.componentGenerics) {
  20. state.componentGenerics = Object.create(null)
  21. }
  22. state.componentGenerics[componentName] = true
  23. return {
  24. type: componentName,
  25. attr: props || {},
  26. children: []
  27. }
  28. },
  29. resolveScopedSlots (slotName, {
  30. genCode,
  31. generate,
  32. ownerName,
  33. parentName,
  34. parentNode,
  35. resourcePath,
  36. paramExprNode,
  37. returnExprNodes,
  38. traverseExpr
  39. }, state) {
  40. if (!state.scopedSlots) {
  41. state.scopedSlots = {}
  42. }
  43. const baseName = `${ownerName}-${parentName}-${slotName}`
  44. let componentName = baseName
  45. if (!hasOwn(state.scopedSlots, baseName)) {
  46. state.scopedSlots[baseName] = 0
  47. }
  48. if (state.scopedSlots[baseName]) {
  49. componentName = baseName + state.scopedSlots[baseName]
  50. }
  51. state.scopedSlots[baseName]++
  52. parentNode.attr['generic:scoped-slots-' + slotName] = componentName
  53. if (!parentNode.attr.generic) {
  54. parentNode.attr.generic = {}
  55. }
  56. parentNode.attr.generic[slotName] = true
  57. // 生成 scopedSlots 文件,包括 json,js,wxml,还需要更新 owner 的 usingComponents
  58. if (!state.files) {
  59. state.files = {}
  60. }
  61. const extname = path.extname(resourcePath)
  62. // TODO 需要存储 resourcePath 相关 json
  63. const templateFile = resourcePath.replace(ownerName + extname, componentName + extname)
  64. const templateContent = generate(traverseExpr(returnExprNodes, state), state)
  65. state.files[templateFile] = templateContent
  66. const jsFile = resourcePath.replace(ownerName + extname, componentName + '.js')
  67. const objectProperties = []
  68. if (t.isObjectPattern(paramExprNode)) {
  69. paramExprNode.properties.forEach(property => {
  70. const key = property.key
  71. const value = property.value
  72. const valueObjectProperties = [
  73. t.objectProperty(t.identifier('type'), t.nullLiteral())
  74. ]
  75. if (t.isIdentifier(value)) {
  76. if (value.name !== key.name) {
  77. state.errors.add(`解构插槽 Prop 时,不支持将${key.name}重命名为${value.name},重命名后会影响性能`)
  78. }
  79. } else if (t.isAssignmentPattern(value)) {
  80. valueObjectProperties.push(t.objectProperty(t.identifier('default'), value.right))
  81. }
  82. objectProperties.push(t.objectProperty(key, t.objectExpression(valueObjectProperties)))
  83. })
  84. } else {
  85. state.errors.add(`目前仅支持解构插槽 ${paramExprNode.name},如 v-slot="{ user }"`)
  86. }
  87. const jsContent = generateJsCode(genCode(t.objectExpression(objectProperties), true))
  88. state.files[jsFile] = jsContent
  89. if (!state.generic) {
  90. state.generic = []
  91. }
  92. // 存储,方便后续生成 json
  93. state.generic.push(componentName)
  94. return ''
  95. }
  96. }