mh-two-thousand-and-two
2024-04-12 3d2ec2fd0578d3ba0a414b0cc4e4a2ae60878596
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const compiler = require('@dcloudio/uni-mp-weixin/lib/uni.compiler.js')
const path = require('path')
const t = require('@babel/types')
const uniI18n = require('@dcloudio/uni-cli-i18n')
 
function generateJsCode (properties = '{}') {
  return `
jd.createComponent({
    generic:true,
    props: ${properties},
    render: function(){}
})
`
}
 
function generateCssCode (filename) {
  return `
@import "./${filename}"
`
}
 
function hasOwn (obj, key) {
  return Object.prototype.hasOwnProperty.call(obj, key)
}
 
module.exports = Object.assign({}, compiler, {
  directive: 'jd:',
  resolveScopedSlots (slotName, {
    genCode,
    generate,
    ownerName,
    parentName,
    parentNode,
    resourcePath,
    paramExprNode,
    returnExprNodes,
    traverseExpr
  }, state) {
    if (!state.scopedSlots) {
      state.scopedSlots = {}
    }
    const baseName = `${ownerName}-${parentName}-${slotName}`
    let componentName = baseName
    if (!hasOwn(state.scopedSlots, baseName)) {
      state.scopedSlots[baseName] = 0
    }
    if (state.scopedSlots[baseName]) {
      componentName = baseName + state.scopedSlots[baseName]
    }
    state.scopedSlots[baseName]++
    parentNode.attr['generic:scoped-slots-' + slotName] = componentName
    if (state.options.platform.name === 'mp-weixin') {
      parentNode.attr['data-vue-generic'] = 'scoped'
    }
    if (!parentNode.attr.generic) {
      parentNode.attr.generic = {}
    }
    parentNode.attr.generic[slotName] = true
 
    // 生成 scopedSlots 文件,包括 json,js,wxml,wxss,还需要更新 owner 的 usingComponents
    if (!state.files) {
      state.files = {}
    }
    const extname = path.extname(resourcePath)
 
    // TODO 需要存储 resourcePath 相关 json
 
    const templateFile = resourcePath.replace(ownerName + extname, componentName + extname)
    const templateContent = generate(traverseExpr(returnExprNodes, state), state)
 
    state.files[templateFile] = templateContent
 
    const jsFile = resourcePath.replace(ownerName + extname, componentName + '.js')
 
    const objectProperties = []
 
    if (t.isObjectPattern(paramExprNode)) {
      paramExprNode.properties.forEach(property => {
        const key = property.key
        const value = property.value
        const valueObjectProperties = [
          t.objectProperty(t.identifier('type'), t.nullLiteral())
        ]
        if (t.isIdentifier(value)) {
          if (value.name !== key.name) {
            state.errors.add(uniI18n.__('mpWeChat.slotPropNoSupportReanme', { 0: key.name, 1: value.name }))
          }
        } else if (t.isAssignmentPattern(value)) {
          valueObjectProperties.push(t.objectProperty(t.identifier('default'), value.right))
        }
        objectProperties.push(t.objectProperty(key, t.objectExpression(valueObjectProperties)))
      })
    } else {
      state.errors.add(uniI18n.__('mpWeChat.onlySupportDestructuringSlot', { 0: paramExprNode.name, 1: 'v-slot="{ user }"' }))
    }
    const jsContent = generateJsCode(genCode(t.objectExpression(objectProperties), true))
    state.files[jsFile] = jsContent
 
    try {
      // TODO 使用 getPlatformExts 在单元测试报错,改从 state.options.platform 判断
      const {
        getPlatformExts
      } = require('@dcloudio/uni-cli-shared')
      const styleExtname = getPlatformExts().style
      const styleFile = resourcePath.replace(ownerName + extname, componentName + styleExtname)
      const styleContent = generateCssCode(ownerName + styleExtname)
 
      state.files[styleFile] = styleContent
    } catch (error) { }
 
    if (!state.generic) {
      state.generic = []
    }
    // 存储,方便后续生成 json
    state.generic.push(componentName)
 
    return ''
  }
})