You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.8 KiB
118 lines
3.8 KiB
const compiler = require('@dcloudio/uni-mp-weixin/lib/uni.compiler.js')
|
|
const path = require('path')
|
|
const t = require('@babel/types')
|
|
|
|
function generateJsCode (properties = '{}') {
|
|
return `
|
|
wx.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: 'tt:',
|
|
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 (!parentNode.attr.generic) {
|
|
parentNode.attr.generic = {}
|
|
}
|
|
parentNode.attr.generic[slotName] = componentName
|
|
|
|
// 生成 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(`解构插槽 Prop 时,不支持将${key.name}重命名为${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(`目前仅支持解构插槽 ${paramExprNode.name},如 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) { }
|
|
|
|
// 用于后续修复字节跳动小程序不支持抽象节点导致的问题
|
|
const fixExtname = '.fix'
|
|
const extFile = resourcePath.replace(ownerName + extname, componentName + fixExtname)
|
|
state.files[extFile] = `${resourcePath.replace(ownerName + extname, ownerName)},${parentName},${componentName},scoped-slots-${slotName}`
|
|
|
|
if (!state.generic) {
|
|
state.generic = []
|
|
}
|
|
// 存储,方便后续生成 json
|
|
state.generic.push(componentName)
|
|
|
|
return ''
|
|
}
|
|
})
|
|
|