Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wzj-java
uni-app
提交
c23516a6
U
uni-app
项目概览
wzj-java
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c23516a6
编写于
6月 25, 2021
作者:
Q
qiang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix(mp): 修复 v-for 嵌套 slot 编译报错的问题 question/125108
上级
7e774b0b
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
129 addition
and
48 deletion
+129
-48
packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js
...ni-template-compiler/__tests__/compiler-mp-alipay.spec.js
+2
-2
packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
...uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
+2
-2
packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js
...ni-template-compiler/__tests__/compiler-mp-weixin.spec.js
+38
-6
packages/uni-template-compiler/lib/script/traverse/index.js
packages/uni-template-compiler/lib/script/traverse/index.js
+3
-17
packages/uni-template-compiler/lib/script/traverse/render-list.js
.../uni-template-compiler/lib/script/traverse/render-list.js
+8
-4
packages/uni-template-compiler/lib/script/traverse/render-slot.js
.../uni-template-compiler/lib/script/traverse/render-slot.js
+5
-2
packages/uni-template-compiler/lib/script/traverse/statements.js
...s/uni-template-compiler/lib/script/traverse/statements.js
+71
-15
未找到文件。
packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js
浏览文件 @
c23516a6
...
...
@@ -115,7 +115,7 @@ describe('mp:compiler-mp-alipay', () => {
assertCodegen
(
'
<view><slot :item="item"><slot></view>
'
,
'
<view><block a:if="{{$slots.$default}}"><slot item="{{item}}"></slot></block><block a:else><slot></slot></block></view>
'
,
'
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
(
'
<view><slot v-bind="object"><slot></view>
'
,
'
<view><block a:if="{{$slots.$default}}"><slot></slot></block><block a:else><slot></slot></block></view>
'
,
'
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
'
}
...
...
packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
浏览文件 @
c23516a6
...
...
@@ -99,7 +99,7 @@ describe('mp:compiler-mp-baidu', () => {
assertCodegen
(
'
<view><slot :item="item"><slot></view>
'
,
'
<view><block s-if="{{$slots.default}}"><slot var-item="item"></slot></block><block s-else><slot></slot></block></view>
'
,
'
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
(
'
<view><slot v-bind="object"><slot></view>
'
,
'
<view><block s-if="{{$slots.default}}"><slot></slot></block><block s-else><slot></slot></block></view>
'
,
'
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
'
}
...
...
packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js
浏览文件 @
c23516a6
...
...
@@ -116,7 +116,39 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen
(
'
<view><slot :item="item"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view>
'
,
'
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
(
'
<view><view v-for="(item,index) in list" :key="index"><slot :item="item"><slot></view></view>
'
,
'
<view><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item.$orig}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view></block></view>
'
,
'
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
(
'
<view><view v-for="(item,index) in list" :key="index"><slot :item="item" :test="test"><slot></view></view>
'
,
'
<view><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item.$orig}}" test="{{test}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view></block></view>
'
,
'
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
(
'
<view><view v-for="(item,index) in list" :key="index"><slot :item="item" :test="test()"><slot></view></view>
'
,
'
<view><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item.$orig}}" test="{{$root.m0}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view></block></view>
'
,
'
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
(
'
<view><view v-for="(item,index) in list" :key="index"><slot :item="item" :test="test()+item"><slot></view></view>
'
,
'
<view><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item.$orig}}" test="{{$root.m0+item.$orig}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view></block></view>
'
,
'
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
(
'
<view><slot :item="getValue(item)"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{$root.m0}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view>
'
,
'
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
(
'
<view><slot v-bind="object"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot></block><block wx:else><slot></slot></block></view>
'
,
'
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
(
'
<view><slot :item="item"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot></block><block wx:else><slot></slot></block></view>
'
,
'
with(this){
$setScopedSlotsParams("default",{"item":item})
}
'
,
'
with(this){
{$setScopedSlotsParams("default",{"item":item})}
}
'
,
{
scopedSlotsCompiler
:
'
augmented
'
}
...
...
@@ -175,7 +207,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen
(
'
<view><slot :item="getValue(item)"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot></block><block wx:else><slot></slot></block></view>
'
,
'
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
(
'
<view><slot v-bind="object"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot></block><block wx:else><slot></slot></block></view>
'
,
'
with(this){
$setScopedSlotsParams("default",object)
}
'
,
'
with(this){
{$setScopedSlotsParams("default",object)}
}
'
,
{
scopedSlotsCompiler
:
'
augmented
'
}
...
...
packages/uni-template-compiler/lib/script/traverse/index.js
浏览文件 @
c23516a6
...
...
@@ -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
)
...
...
packages/uni-template-compiler/lib/script/traverse/render-list.js
浏览文件 @
c23516a6
...
...
@@ -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
)
...
...
packages/uni-template-compiler/lib/script/traverse/render-slot.js
浏览文件 @
c23516a6
...
...
@@ -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
.
clone
Deep
(
path
.
nod
e
))
properties
.
push
(
state
.
options
.
scopedSlotsCompiler
===
'
auto
'
?
path
.
node
:
t
.
clone
Node
(
path
.
node
,
tru
e
))
})
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 组件嵌套
}
packages/uni-template-compiler/lib/script/traverse/statements.js
浏览文件 @
c23516a6
...
...
@@ -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
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录