diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js
index a6cc18ea665724a8cdfff92832f7514980ee2ff8..2c918ac05a822affc612d9567edff37acf4b69bb 100644
--- a/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js
+++ b/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js
@@ -115,7 +115,7 @@ describe('mp:compiler-mp-alipay', () => {
assertCodegen(
'',
'',
- 'with(this){if($scope.props.scopedSlotsCompiler==="augmented"){const $root=$mp.data.$root;$setScopedSlotsParams("default",{"item":item})}}',
+ 'with(this){if($scope.props.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":item})}}',
{
scopedSlotsCompiler: 'auto'
}
@@ -123,7 +123,7 @@ describe('mp:compiler-mp-alipay', () => {
assertCodegen(
'',
'',
- 'with(this){if($scope.props.scopedSlotsCompiler==="augmented"){const $root=$mp.data.$root;$setScopedSlotsParams("default",object)}}',
+ 'with(this){if($scope.props.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",object)}}',
{
scopedSlotsCompiler: 'auto'
}
diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
index c0ecdefa1e2f1331386932e192f1bf15b105ab14..9e05a96a027a63390c930d1eac2af6c34e1a04ab 100644
--- a/packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
+++ b/packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
@@ -99,7 +99,7 @@ describe('mp:compiler-mp-baidu', () => {
assertCodegen(
'',
'',
- 'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){const $root=$mp.data.$root;$setScopedSlotsParams("default",{"item":item})}}',
+ 'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":item})}}',
{
scopedSlotsCompiler: 'auto'
}
@@ -107,7 +107,7 @@ describe('mp:compiler-mp-baidu', () => {
assertCodegen(
'',
'',
- 'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){const $root=$mp.data.$root;$setScopedSlotsParams("default",object)}}',
+ 'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",object)}}',
{
scopedSlotsCompiler: 'auto'
}
diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js
index a5e83b0b1f25eac42158585d9250f91393d040f7..6eab4f18dbbed24356cd5a201a2999c18a95f1e3 100644
--- a/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js
+++ b/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js
@@ -116,7 +116,39 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen(
'',
'',
- 'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){const $root=$mp.data.$root;$setScopedSlotsParams("default",{"item":item})}}',
+ 'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":item})}}',
+ {
+ scopedSlotsCompiler: 'auto'
+ }
+ )
+ assertCodegen(
+ '',
+ '',
+ 'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":$orig})}return{$orig:$orig}});$mp.data=Object.assign({},{$root:{l0:l0}})}',
+ {
+ scopedSlotsCompiler: 'auto'
+ }
+ )
+ assertCodegen(
+ '',
+ '',
+ 'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":$orig,"test":test})}return{$orig:$orig}});$mp.data=Object.assign({},{$root:{l0:l0}})}',
+ {
+ scopedSlotsCompiler: 'auto'
+ }
+ )
+ assertCodegen(
+ '',
+ '',
+ 'with(this){var m0=test();var l0=__map(list,function(item,index){var $orig=__get_orig(item);if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":$orig,"test":m0})}return{$orig:$orig}});$mp.data=Object.assign({},{$root:{m0:m0,l0:l0}})}',
+ {
+ scopedSlotsCompiler: 'auto'
+ }
+ )
+ assertCodegen(
+ '',
+ '',
+ 'with(this){var m0=test();var l0=__map(list,function(item,index){var $orig=__get_orig(item);if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":$orig,"test":m0+$orig})}return{$orig:$orig}});$mp.data=Object.assign({},{$root:{m0:m0,l0:l0}})}',
{
scopedSlotsCompiler: 'auto'
}
@@ -124,7 +156,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen(
'',
'',
- 'with(this){var m0=getValue(item);$mp.data=Object.assign({},{$root:{m0:m0}});if($scope.data.scopedSlotsCompiler==="augmented"){const $root=$mp.data.$root;$setScopedSlotsParams("default",{"item":$root.m0})}}',
+ 'with(this){var m0=getValue(item);$mp.data=Object.assign({},{$root:{m0:m0}});if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":m0})}}',
{
scopedSlotsCompiler: 'auto'
}
@@ -132,7 +164,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen(
'',
'',
- 'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){const $root=$mp.data.$root;$setScopedSlotsParams("default",object)}}',
+ 'with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",object)}}',
{
scopedSlotsCompiler: 'auto'
}
@@ -167,7 +199,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen(
'',
'',
- 'with(this){$setScopedSlotsParams("default",{"item":item})}',
+ 'with(this){{$setScopedSlotsParams("default",{"item":item})}}',
{
scopedSlotsCompiler: 'augmented'
}
@@ -175,7 +207,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen(
'',
'',
- 'with(this){$setScopedSlotsParams("default",{"item":getValue(item)})}',
+ 'with(this){{$setScopedSlotsParams("default",{"item":getValue(item)})}}',
{
scopedSlotsCompiler: 'augmented'
}
@@ -183,7 +215,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen(
'',
'',
- 'with(this){$setScopedSlotsParams("default",object)}',
+ 'with(this){{$setScopedSlotsParams("default",object)}}',
{
scopedSlotsCompiler: 'augmented'
}
diff --git a/packages/uni-template-compiler/lib/script/traverse/index.js b/packages/uni-template-compiler/lib/script/traverse/index.js
index 6cd2f5b0f30c6a5c37394eb9587f516676a6c123..723ccb6bb749d7eb24ce2a3561969b77e2489cdc 100644
--- a/packages/uni-template-compiler/lib/script/traverse/index.js
+++ b/packages/uni-template-compiler/lib/script/traverse/index.js
@@ -24,7 +24,8 @@ const {
const {
getInItIfStatement,
- getDataExpressionStatement
+ getDataExpressionStatement,
+ getRenderSlotStatement
} = require('./statements')
const visitor = require('./visitor')
@@ -114,22 +115,7 @@ module.exports = function traverse (ast, state) {
}
if (renderSlotStatementArray.length) {
- if (state.options.scopedSlotsCompiler === 'auto') {
- const node = 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')
- ),
- t.blockStatement([
- t.variableDeclaration('const', [t.variableDeclarator(t.identifier('$root'),
- t.memberExpression(t.memberExpression(t.identifier('$mp'), t.identifier('data')), t.identifier('$root'))
- )]),
- ...renderSlotStatementArray
- ])
- )
- blockStatementBody.push(node)
- } else {
- blockStatementBody.push(...renderSlotStatementArray)
- }
+ blockStatementBody.push(getRenderSlotStatement(state, renderSlotStatementArray))
}
reIdentifier(identifierArray)
diff --git a/packages/uni-template-compiler/lib/script/traverse/render-list.js b/packages/uni-template-compiler/lib/script/traverse/render-list.js
index a9f3b7c55e28a6f47e47735f8594b57042dd9e93..ae7c662cb13cf22df8214289365689416975b089 100644
--- a/packages/uni-template-compiler/lib/script/traverse/render-list.js
+++ b/packages/uni-template-compiler/lib/script/traverse/render-list.js
@@ -135,7 +135,8 @@ module.exports = function traverseRenderList (path, state) {
forIndex,
forExtra: getForExtra(forItem, forIndex, path, state),
propertyArray: [],
- declarationArray: []
+ declarationArray: [],
+ renderSlotStatementArray: []
}
const forState = {
@@ -149,13 +150,14 @@ module.exports = function traverseRenderList (path, state) {
propertyArray: [],
declarationArray: [],
computedProperty: {},
- initExpressionStatementArray: state.initExpressionStatementArray
+ initExpressionStatementArray: state.initExpressionStatementArray,
+ renderSlotStatementArray: state.renderSlotStatementArray
}
functionExpression.traverse(require('./visitor'), forState)
const forPath = path.get('arguments.0')
- if (forStateScoped.propertyArray.length) {
+ if (forStateScoped.propertyArray.length || forStateScoped.renderSlotStatementArray.length) {
// for => map
forPath.replaceWith(
getMemberExpr(
@@ -165,9 +167,11 @@ module.exports = function traverseRenderList (path, state) {
forPath.node,
forStateScoped.propertyArray,
forStateScoped.declarationArray,
+ forStateScoped.renderSlotStatementArray,
[], // eventPropertyArray
forItem,
- forIndex
+ forIndex,
+ state
),
forState
)
diff --git a/packages/uni-template-compiler/lib/script/traverse/render-slot.js b/packages/uni-template-compiler/lib/script/traverse/render-slot.js
index abb541e821252d0842a7446bfe3706593b548f2b..e7df06c7bbd3dcc3c507c912c4ab6d6e1ec64da6 100644
--- a/packages/uni-template-compiler/lib/script/traverse/render-slot.js
+++ b/packages/uni-template-compiler/lib/script/traverse/render-slot.js
@@ -15,7 +15,7 @@ module.exports = function getRenderSlot (path, state) {
const newProperties = []
propertiesPath.forEach(path => {
const properties = path.get('key').isStringLiteral({ value: 'SLOT_DEFAULT' }) ? oldProperties : newProperties
- properties.push(state.options.scopedSlotsCompiler === 'auto' ? path.node : t.cloneDeep(path.node))
+ properties.push(state.options.scopedSlotsCompiler === 'auto' ? path.node : t.cloneNode(path.node, true))
})
if (!newProperties.length) {
return
@@ -29,7 +29,10 @@ module.exports = function getRenderSlot (path, state) {
}
}
if (valueNode) {
- state.renderSlotStatementArray.push(t.expressionStatement(t.callExpression(t.identifier('$setScopedSlotsParams'), [t.stringLiteral(name.node.value), valueNode])))
+ const scoped = state.scoped
+ // TODO 判断是否包含作用域内变量
+ const renderSlotStatementArray = scoped && scoped.length ? scoped[scoped.length - 1].renderSlotStatementArray : state.renderSlotStatementArray
+ renderSlotStatementArray.push(t.expressionStatement(t.callExpression(t.identifier('$setScopedSlotsParams'), [t.stringLiteral(name.node.value), valueNode])))
}
// TODO 组件嵌套
}
diff --git a/packages/uni-template-compiler/lib/script/traverse/statements.js b/packages/uni-template-compiler/lib/script/traverse/statements.js
index 8d2725c29a061c31f7cad4c7eaface48c4e8a443..0c5211e2857a0007e3dd2630a2e71ec782ee599c 100644
--- a/packages/uni-template-compiler/lib/script/traverse/statements.js
+++ b/packages/uni-template-compiler/lib/script/traverse/statements.js
@@ -4,7 +4,9 @@ const {
VAR_MP,
VAR_ROOT,
VAR_ORIGINAL,
- INTERNAL_GET_ORIG
+ INTERNAL_GET_ORIG,
+ IDENTIFIER_METHOD,
+ IDENTIFIER_FILTER
} = require('../../constants')
/**
* e0=e=>count++
@@ -31,6 +33,53 @@ function getInItIfStatement (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 {}})
*/
@@ -38,9 +87,11 @@ function getMapCallExpression (
object,
objectPropertyArray,
declarationArray,
+ renderSlotStatementArray,
eventPropertyArray,
forItem,
- forIndex
+ forIndex,
+ state
) {
const blockStatement = []
// var $orgi = __get_orig(forItem)
@@ -49,24 +100,28 @@ function getMapCallExpression (
t.identifier(forItem)
]))
]))
-
if (declarationArray.length) {
declarationArray.forEach(declaration => {
blockStatement.push(declaration)
})
- blockStatement.push(t.returnStatement(
- // return {$orgi:$orgi}
- t.objectExpression(
- [
- t.objectProperty(
- t.identifier(VAR_ORIGINAL),
- t.identifier(VAR_ORIGINAL)
- )
- ].concat(objectPropertyArray)
- )
- ))
}
+ 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)
+ )
+ ))
+
const params = [t.identifier(forItem)]
if (forIndex) {
params.push(t.identifier(forIndex))
@@ -119,5 +174,6 @@ module.exports = {
getInItIfStatement,
getMapCallExpression,
getDataExpressionStatement,
- getEventExpressionStatement
+ getEventExpressionStatement,
+ getRenderSlotStatement
}