Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
uni-app
提交
96443dee
U
uni-app
项目概览
DCloud
/
uni-app
3 个月 前同步成功
通知
725
Star
38705
Fork
3642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
7
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
7
Issue
7
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
96443dee
编写于
7月 27, 2020
作者:
Q
qiang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: 解决v-for中方法使用复杂表达式报错的问题 fixed #373
上级
68cd6c67
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
62 addition
and
12 deletion
+62
-12
packages/uni-template-compiler/__tests__/compiler.spec.js
packages/uni-template-compiler/__tests__/compiler.spec.js
+6
-0
packages/uni-template-compiler/lib/constants.js
packages/uni-template-compiler/lib/constants.js
+2
-1
packages/uni-template-compiler/lib/script/traverse/data/event.js
...s/uni-template-compiler/lib/script/traverse/data/event.js
+48
-8
packages/uni-template-compiler/lib/script/traverse/visitor.js
...ages/uni-template-compiler/lib/script/traverse/visitor.js
+1
-1
src/core/runtime/wrapper/util.js
src/core/runtime/wrapper/util.js
+5
-2
未找到文件。
packages/uni-template-compiler/__tests__/compiler.spec.js
浏览文件 @
96443dee
...
...
@@ -326,6 +326,12 @@ describe('mp:compiler', () => {
'
<input @input="onInput($event, 2+2);">
'
,
'
<input data-event-opts="{{[[
\'
input
\'
,[[
\'
onInput
\'
,[
\'
$event
\'
,2+2]]]]]}}" bindinput="__e"/>
'
)
// v-for
assertCodegen
(
'
<view v-for="(item,index) in list" :key="index"><view @click="$test.test(item)">test</view></view>
'
,
'
<block wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><view data-event-opts="{{[[
\'
tap
\'
,[[
\'
e0
\'
,[
\'
$event
\'
]]]]]}}" data-event-params="{{[{item}]}}" bindtap="__e">test</view></view></block>
'
,
'
with(this){if(!_isMounted){e0=function($event,item){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=(_temp.eventParams||_temp["event-params"])[0],item=_temp2.item;var _temp,_temp2;return $test.test(item)}}}
'
)
// tricky symbols in args
// assertCodegen(
// `<input @input="onInput(');[\\'());');">`,
...
...
packages/uni-template-compiler/lib/constants.js
浏览文件 @
96443dee
...
...
@@ -62,6 +62,7 @@ module.exports = {
VAR_FILTER
:
'
F
'
,
ATTR_DATA_EVENT_OPTS
:
'
data-event-opts
'
,
ATTR_DATA_COM_TYPE
:
'
data-com-type
'
,
ATTR_DATA_EVENT_PARAMS
:
'
data-event-params
'
,
INTERNAL_GET_ORIG
,
INTERNAL_GET_CLASS
,
INTERNAL_GET_STYLE
,
...
...
@@ -120,4 +121,4 @@ module.exports = {
IDENTIFIER_STYLE
:
'
__$$style$$__
'
,
IDENTIFIER_EVENT
:
'
__$$event$$__
'
,
IDENTIFIER_GLOBAL
:
'
__$$global$$__
'
}
}
packages/uni-template-compiler/lib/script/traverse/data/event.js
浏览文件 @
96443dee
const
t
=
require
(
'
@babel/types
'
)
const
parser
=
require
(
'
@babel/parser
'
)
const
{
IDENTIFIER_EVENT
,
VUE_EVENT_MODIFIERS
,
INTERNAL_EVENT_PROXY
,
ATTR_DATA_EVENT_OPTS
,
ATTR_DATA_EVENT_PARAMS
,
INTERNAL_SET_SYNC
}
=
require
(
'
../../../constants
'
)
...
...
@@ -212,8 +214,9 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
let
isOnce
=
false
const
methods
=
[]
const
params
=
[]
if
(
type
)
{
if
(
type
)
{
isPassive
=
type
.
charAt
(
0
)
===
VUE_EVENT_MODIFIERS
.
passive
type
=
isPassive
?
type
.
slice
(
1
)
:
type
...
...
@@ -318,7 +321,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
ReturnStatement
(
path
)
{
const
argument
=
path
.
node
.
argument
if
(
t
.
isCallExpression
(
argument
))
{
if
(
t
.
isIdentifier
(
argument
.
callee
))
{
if
(
t
.
isIdentifier
(
argument
.
callee
))
{
// || t.isMemberExpression(argument.callee)
anonymous
=
false
parseEventByCallExpression
(
argument
,
methods
)
}
...
...
@@ -326,6 +329,27 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
}
})
if
(
anonymous
)
{
// 处理复杂表达式中使用的局部变量(主要在v-for中定义)
funcPath
.
traverse
({
Identifier
(
path
)
{
const
scope
=
path
.
scope
const
node
=
path
.
node
const
name
=
node
.
name
if
(
path
.
key
!==
'
key
'
&&
path
.
key
!==
'
property
'
&&
scope
&&
!
scope
.
hasOwnBinding
(
name
)
&&
scope
.
hasBinding
(
name
))
{
params
.
push
(
name
)
}
}
})
params
.
forEach
(
name
=>
{
funcPath
.
node
.
params
.
push
(
t
.
identifier
(
name
))
})
if
(
params
.
length
)
{
const
datasetUid
=
funcPath
.
scope
.
generateDeclaredUidIdentifier
().
name
const
paramsUid
=
funcPath
.
scope
.
generateDeclaredUidIdentifier
().
name
const
dataset
=
ATTR_DATA_EVENT_PARAMS
.
substring
(
5
)
const
code
=
`var
${
datasetUid
}
=arguments[arguments.length-1].currentTarget.dataset,
${
paramsUid
}
=(
${
datasetUid
}
.
${
dataset
.
replace
(
/-
([
a-z
])
/
,
(
_
,
str
)
=>
str
.
toUpperCase
())}
||
${
datasetUid
}
['
${
dataset
}
'])[0],
${
params
.
map
(
item
=>
`
${
item
}
=
${
paramsUid
}
.
${
item
}
`
).
join
(
'
,
'
)}
`
funcPath
.
node
.
body
.
body
.
unshift
(
parser
.
parse
(
code
).
program
.
body
[
0
])
}
methods
.
push
(
addEventExpressionStatement
(
funcPath
,
state
,
isComponent
,
isNativeOn
))
}
}
...
...
@@ -334,6 +358,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
return
{
type
,
params
,
methods
,
modifiers
:
{
isCatch
,
...
...
@@ -358,6 +383,7 @@ function _processEvent (path, state, isComponent, isNativeOn = false, tagName, r
const
valuePath
=
propertyPath
.
get
(
'
value
'
)
const
{
type
,
params
,
methods
,
modifiers
:
{
isCatch
,
...
...
@@ -393,12 +419,13 @@ function _processEvent (path, state, isComponent, isNativeOn = false, tagName, r
if
(
isCustom
)
{
optType
=
VUE_EVENT_MODIFIERS
.
custom
+
optType
}
opts
.
push
(
t
.
arrayExpression
([
opts
.
push
(
{
opt
:
t
.
arrayExpression
([
t
.
stringLiteral
(
optType
),
t
.
arrayExpression
(
methods
)
])
)
]),
params
})
keyPath
.
replaceWith
(
t
.
stringLiteral
(
...
...
@@ -422,15 +449,18 @@ module.exports = function processEvent (paths, path, state, isComponent, tagName
const
ret
=
[]
const
opts
=
[]
const
params
=
[]
if
(
onPath
)
{
_processEvent
(
onPath
,
state
,
isComponent
,
false
,
tagName
,
ret
).
forEach
(
opt
=>
{
_processEvent
(
onPath
,
state
,
isComponent
,
false
,
tagName
,
ret
).
forEach
(
({
opt
,
params
:
array
})
=>
{
opts
.
push
(
opt
)
params
.
push
(...
array
)
})
}
if
(
nativeOnPath
)
{
_processEvent
(
nativeOnPath
,
state
,
isComponent
,
true
,
tagName
,
ret
).
forEach
(
opt
=>
{
_processEvent
(
nativeOnPath
,
state
,
isComponent
,
true
,
tagName
,
ret
).
forEach
(
({
opt
,
params
:
array
})
=>
{
opts
.
push
(
opt
)
params
.
push
(...
array
)
})
}
if
(
!
opts
.
length
)
{
...
...
@@ -444,5 +474,15 @@ module.exports = function processEvent (paths, path, state, isComponent, tagName
)
)
if
(
params
.
length
)
{
ret
.
push
(
t
.
objectProperty
(
t
.
stringLiteral
(
ATTR_DATA_EVENT_PARAMS
),
// 使用数组格式,直接使用对象格式微信小程序编译会报错
t
.
stringLiteral
(
`{{[{
${
params
.
join
(
'
,
'
)}
}]}}`
)
)
)
}
return
ret
}
packages/uni-template-compiler/lib/script/traverse/visitor.js
浏览文件 @
96443dee
...
...
@@ -132,7 +132,7 @@ function checkUsingGlobalComponents (name, globalUsingComponents, state) {
}
module
.
exports
=
{
noScope
:
tru
e
,
noScope
:
fals
e
,
MemberExpression
(
path
)
{
if
(
// t.m(123)
t
.
isIdentifier
(
path
.
node
.
object
)
&&
...
...
src/core/runtime/wrapper/util.js
浏览文件 @
96443dee
...
...
@@ -542,14 +542,17 @@ export function handleEvent (event) {
}
handler
.
once
=
true
}
ret
.
push
(
handler
.
apply
(
handlerCtx
,
processEventArgs
(
const
params
=
processEventArgs
(
this
.
$vm
,
event
,
eventArray
[
1
],
eventArray
[
2
],
isCustom
,
methodName
)))
)
||
[]
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret
.
push
(
handler
.
apply
(
handlerCtx
,
params
.
concat
([,
,
,
,
,
,
,
,
,
,
event
])))
}
})
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录