提交 cfc2bae3 编写于 作者: Q qiang

fix(mp): event in v-for (question/171043)

上级 924aec31
......@@ -416,6 +416,20 @@ describe('mp:compiler-extra', () => {
'<block wx:for="{{$root.l0}}" wx:for-item="value" wx:for-index="key" wx:key="$index"><view><button data-event-opts="{{[[\'tap\',[[\'click1\',[value.$index]]]]]}}" bindtap="__e">click1(index)</button><button data-event-opts="{{[[\'tap\',[[\'e0\',[\'$event\']]]]]}}" data-event-params="{{({value:value.$orig})}}" bindtap="__e">fnObj.click(value)</button></view></block>',
'with(this){var l0=__map(dataObj,function(value,key,index){var $orig=__get_orig(value);return{$orig:$orig,$index:index}});if(!_isMounted){e0=function($event,value){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],value=_temp2.value;var _temp,_temp2;return fnObj.click(value)}}$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
`<view v-for="(value,key,index) in obj" :key="key" @click="test(index)">
<view v-for="(item,key1,index1) in value" :key="key1" @click="test(index1)">text</view>
</view>`,
'<block wx:for="{{$root.l1}}" wx:for-item="value" wx:for-index="key" wx:key="key"><view data-event-opts="{{[[\'tap\',[[\'test\',[value.$index]]]]]}}" bindtap="__e"><block wx:for="{{value.l0}}" wx:for-item="item" wx:for-index="key1" wx:key="key1"><view data-event-opts="{{[[\'tap\',[[\'test\',[item.$index]]]]]}}" bindtap="__e">text</view></block></view></block>',
'with(this){var l1=__map(obj,function(value,key,index){var $orig=__get_orig(value);var l0=__map(value,function(item,key1,index1){var $orig=__get_orig(item);return{$orig:$orig,$index:index1}});return{$orig:$orig,l0:l0,$index:index}});$mp.data=Object.assign({},{$root:{l1:l1}})}'
)
assertCodegen(
`<view v-for="(value,key,index) in obj" :key="key" @click="test(index)">
<view v-for="(item,index1) in value" :key="key1" @click="test(index1)">text</view>
</view>`,
'<block wx:for="{{$root.l0}}" wx:for-item="value" wx:for-index="key" wx:key="key"><view data-event-opts="{{[[\'tap\',[[\'test\',[value.$index]]]]]}}" bindtap="__e"><block wx:for="{{value.$orig}}" wx:for-item="item" wx:for-index="index1" wx:key="*this"><view data-event-opts="{{[[\'tap\',[[\'e0\',[\'$event\']]]]]}}" data-event-params="{{({index1})}}" bindtap="__e">text</view></block></view></block>',
'with(this){var l0=__map(obj,function(value,key,index){var $orig=__get_orig(value);return{$orig:$orig,$index:index}});if(!_isMounted){e0=function($event,index1){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],index1=_temp2.index1;var _temp,_temp2;return test(index1)}}$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
})
it('generate class binding', () => {
......
......@@ -232,15 +232,20 @@ function isValuePath (path) {
return path.key !== 'key' && path.key !== 'id' && (path.key !== 'property' || path.parent.computed) && !(path.key === 'value' && path.parentPath.parentPath.isObjectPattern()) && !(path.key === 'left' && path.parentPath.parentPath.parentPath.isObjectPattern())
}
/**
* 判断 v-for 中是否包含复杂表达式:数组、对象、方法
*/
const isSafeScoped = (state) => {
const scopedArray = state.scoped
let checkForIndex = false
for (let index = 0; index < scopedArray.length; index++) {
const scoped = scopedArray[index]
const arrayExtra = scoped.forExtra[0].elements[0].value
// 简易判断
// 判断仅外层遍历对象是否包含了 index 参数
if (checkForIndex && scoped.forIndex && scoped.forKey) {
return false
}
if (index === 0 && !(scoped.forIndex && scoped.forKey)) {
checkForIndex = true
}
// 简易判断 v-for 中是否包含复杂表达式:数组、对象、方法
if (typeof arrayExtra === 'string' && (arrayExtra.startsWith('[') || arrayExtra.startsWith('{') || /\(.*\)/.test(arrayExtra))) {
return false
}
......@@ -320,7 +325,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
// "click":function($event) {click1(item);click2(item);}
const body = funcPath.node.body && funcPath.node.body.body
const funcParams = funcPath.node.params
if (body && body.length && funcParams && funcParams.length === 1 && !hasMemberExpression(funcPath)) {
if (body && body.length && funcParams && funcParams.length === 1 && !hasMemberExpression(funcPath) && isSafeScoped(state)) {
const exprStatements = body.filter(node => {
return t.isExpressionStatement(node) && t.isCallExpression(node.expression) && !node.expression.arguments.find(element => {
// click1(item().a)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册