From c23516a60cec5fed4c500ed873949a2ab13dec85 Mon Sep 17 00:00:00 2001 From: qiang Date: Fri, 25 Jun 2021 17:18:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(mp):=20=E4=BF=AE=E5=A4=8D=20v-for=20?= =?UTF-8?q?=E5=B5=8C=E5=A5=97=20slot=20=E7=BC=96=E8=AF=91=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98=20question/125108?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__tests__/compiler-mp-alipay.spec.js | 4 +- .../__tests__/compiler-mp-baidu.spec.js | 4 +- .../__tests__/compiler-mp-weixin.spec.js | 44 ++++++++-- .../lib/script/traverse/index.js | 20 +---- .../lib/script/traverse/render-list.js | 12 ++- .../lib/script/traverse/render-slot.js | 7 +- .../lib/script/traverse/statements.js | 86 +++++++++++++++---- 7 files changed, 129 insertions(+), 48 deletions(-) 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 a6cc18ea6..2c918ac05 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 c0ecdefa1..9e05a96a0 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 a5e83b0b1..6eab4f18d 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 6cd2f5b0f..723ccb6bb 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 a9f3b7c55..ae7c662cb 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 abb541e82..e7df06c7b 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 8d2725c29..0c5211e28 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 } -- GitLab