刮刮前端
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.
 
 
 
 

188 lines
4.6 KiB

const t = require('@babel/types')
const {
VAR_MP,
VAR_ROOT,
VAR_ORIGINAL,
VAR_INDEX,
INTERNAL_GET_ORIG,
IDENTIFIER_METHOD,
IDENTIFIER_FILTER
} = require('../../constants')
/**
* e0=e=>count++
*/
function getEventExpressionStatement (left, right) {
return t.expressionStatement(
t.assignmentExpression(
'=',
left,
right
)
)
}
/**
* if(!_isMounted){}
*/
function getInItIfStatement (expressionStatementArray) {
return t.ifStatement(
t.unaryExpression(
'!',
t.identifier('_isMounted')
),
t.blockStatement(expressionStatementArray)
)
}
function getRenderSlotStatement (state, renderSlotStatementArray, forItem) {
function cloneNode (node) {
if (Array.isArray(node)) {
return node.map(function (item) {
return cloneNode(item)
})
} else if (typeof node === 'object') {
if (!node) {
return node
}
if (t.isMemberExpression(node)) { // 纠正被处理过的对象
const name = node.object.name
// identifier 使用原值以被后续修改
if ((name === VAR_ROOT || name === forItem) && t.isIdentifier(node.property) && [IDENTIFIER_METHOD, IDENTIFIER_FILTER].includes(node.property.name)) {
return node.property
}
} else if (t.isIdentifier(node, { name: forItem })) { // 预处理 forItem
return t.identifier(VAR_ORIGINAL)
}
const target = Object.create(node)
Object.keys(node).forEach(function (key) {
target[key] = cloneNode(node[key])
})
return target
} else {
return node
}
}
renderSlotStatementArray.forEach(renderSlotStatement => {
const argument = renderSlotStatement.expression.arguments[1]
if (t.isObjectExpression(argument)) {
// 克隆以避免影响模板
argument.properties = cloneNode(argument.properties)
}
})
const blockStatement = t.blockStatement(renderSlotStatementArray)
if (state.options.scopedSlotsCompiler === 'auto') {
return t.ifStatement(
t.binaryExpression('===',
t.memberExpression(t.memberExpression(t.identifier('$scope'), t.identifier(state.options.platform.name === 'mp-alipay' ? 'props' : 'data')), t.identifier('scopedSlotsCompiler')), t.stringLiteral('augmented')
),
blockStatement
)
}
return blockStatement
}
/**
* items.map(function(item,index){return {}})
*/
function getMapCallExpression (
object,
objectPropertyArray,
declarationArray,
renderSlotStatementArray,
eventPropertyArray,
forItem,
forKey,
forIndex,
state
) {
const blockStatement = []
// var $orgi = __get_orig(forItem)
blockStatement.push(t.variableDeclaration('var', [
t.variableDeclarator(t.identifier(VAR_ORIGINAL), t.callExpression(t.identifier(INTERNAL_GET_ORIG), [
t.identifier(forItem)
]))
]))
if (declarationArray.length) {
declarationArray.forEach(declaration => {
blockStatement.push(declaration)
})
}
if (renderSlotStatementArray.length) {
blockStatement.push(getRenderSlotStatement(state, renderSlotStatementArray, forItem))
}
blockStatement.push(t.returnStatement(
// return {$orgi:$orgi}
t.objectExpression(
[
t.objectProperty(
t.identifier(VAR_ORIGINAL),
t.identifier(VAR_ORIGINAL)
)
].concat(objectPropertyArray)
.concat(forKey && forIndex ? [t.objectProperty(
t.identifier(VAR_INDEX),
t.identifier(forIndex)
)] : [])
)
))
const params = [t.identifier(forItem)]
if (forKey) {
params.push(t.identifier(forKey))
}
if (forIndex) {
params.push(t.identifier(forIndex))
}
return t.callExpression(t.identifier('__map'), [
object,
t.functionExpression(
null,
params,
t.blockStatement(blockStatement)
)
])
}
/**
* $mp.data = Object.assign({},{$root:{}})
*/
function getDataExpressionStatement (objectPropertyArray) {
return t.expressionStatement(
t.assignmentExpression(
'=',
t.memberExpression(
// left
t.identifier(VAR_MP),
t.identifier('data')
),
t.callExpression(
// right
t.memberExpression(
// Object.assign
t.identifier('Object'),
t.identifier('assign')
),
[
t.objectExpression([]), // {}
t.objectExpression([
// {$root:{}}
t.objectProperty(
t.identifier(VAR_ROOT),
t.objectExpression(objectPropertyArray)
)
])
]
)
)
)
}
module.exports = {
getInItIfStatement,
getMapCallExpression,
getDataExpressionStatement,
getEventExpressionStatement,
getRenderSlotStatement
}