提交 0455765d 编写于 作者: Q qiang

fix: MemberExpression with CallExpression in event (question/162570)

上级 c9f3bafd
......@@ -21,22 +21,22 @@ describe('mp:compiler-extra', () => {
'<view @touchmove="a.touchmove">{{t.a}}{{t[\'a\']}}{{t.a(b)}}{{t[\'a\'](b)}}{{u.t.a(b)}}{{u.t.a}}</view>',
'<view bindtouchmove="{{a.touchmove}}">{{t.a+t[\'a\']+t.a(b)+t[\'a\'](b)+$root.g0+u.t.a}}</view>',
'with(this){var g0=u.t.a(b);$mp.data=Object.assign({},{$root:{g0:g0}})}', {
filterModules: {
t: {},
a: {}
}
filterModules: {
t: {},
a: {}
}
}
)
assertCodegen(
/* eslint-disable no-template-curly-in-string */
'<view v-for="(item, index) in a.test()" :key="index">{{item}}</view>',
'<block wx:for="{{a.test()}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view>{{item}}</view></block>',
'with(this){}', {
filterModules: {
t: {},
a: {}
}
filterModules: {
t: {},
a: {}
}
}
)
})
......@@ -45,43 +45,43 @@ describe('mp:compiler-extra', () => {
'<view></view>',
'<view class="data-v-1"></view>',
undefined, {
scopeId: 'data-v-1'
}
scopeId: 'data-v-1'
}
)
assertCodegen(
'<view class="view"></view>',
'<view class="view data-v-2"></view>',
undefined, {
scopeId: 'data-v-2'
}
scopeId: 'data-v-2'
}
)
assertCodegen(
'<view :class="[{ active: isActive }, errorClass]"></view>',
'<view class="{{[\'data-v-3\',[(isActive)?\'active\':\'\'],errorClass]}}"></view>',
undefined, {
scopeId: 'data-v-3'
}
scopeId: 'data-v-3'
}
)
assertCodegen(
'<view class="static" :class="[{ active: isActive }, errorClass]"></view>',
'<view class="{{[\'static\',\'data-v-4\',[(isActive)?\'active\':\'\'],errorClass]}}"></view>',
undefined, {
scopeId: 'data-v-4'
}
scopeId: 'data-v-4'
}
)
assertCodegen(
'<view ref="ref" :class="[{ active: isActive }, errorClass]"></view>',
'<view data-ref="ref" class="{{[\'data-v-5\',\'vue-ref\',[(isActive)?\'active\':\'\'],errorClass]}}"></view>',
undefined, {
scopeId: 'data-v-5'
}
scopeId: 'data-v-5'
}
)
assertCodegen(
'<view :class="view"></view>',
'<view class="{{[\'data-v-6\',view]}}"></view>',
undefined, {
scopeId: 'data-v-6'
}
scopeId: 'data-v-6'
}
)
// assertCodegen(
// '<view :class="view"></view>',
......@@ -94,8 +94,8 @@ describe('mp:compiler-extra', () => {
'<view :class="view" class="view"></view>',
'<view class="{{[\'view\',\'data-v-7\',view]}}"></view>',
undefined, {
scopeId: 'data-v-7'
}
scopeId: 'data-v-7'
}
)
// assertCodegen(
// '<view :class="view" class="view"></view>',
......@@ -124,8 +124,8 @@ describe('mp:compiler-extra', () => {
'<view style="height:100rpx;width:100rpx;">text</view>',
undefined,
undefined, {
transformPx: true
}
transformPx: true
}
)
})
......@@ -763,7 +763,12 @@ describe('mp:compiler-extra', () => {
)
assertCodegen(
'<button type="primary" @click="test(arr, arr[index+1])">click me</button>',
'<button type="primary" data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\',\'$1\'],[\'arr\',\'arr.\'+index+1+\'\']]]]]}}" bindtap="__e">click me</button>'
'<button type="primary" data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\',\'$1\'],[\'arr\',\'arr.\'+(index+1)+\'\']]]]]}}" bindtap="__e">click me</button>'
)
assertCodegen(
'<button type="primary" @click="test(arr, arr[getVal(index+1)])">click me</button>',
'<button type="primary" data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\',\'$1\'],[\'arr\',\'arr.\'+$root.m0+\'\']]]]]}}" bindtap="__e">click me</button>',
'with(this){var m0=getVal(index+1);$mp.data=Object.assign({},{$root:{m0:m0}})}'
)
assertCodegen(
'<button type="primary" @click="test(arr, arr[0])">click me</button>',
......@@ -773,6 +778,20 @@ describe('mp:compiler-extra', () => {
'<view v-for="item in list" @click="test(item)">{{ item }}</view>',
'<block wx:for="{{list}}" wx:for-item="item" wx:for-index="__i0__"><view data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\'],[[[\'list\',\'\',__i0__]]]]]]]}}" bindtap="__e">{{item}}</view></block>'
)
assertCodegen(
'<view v-for="item in list" @click="test(arr[item])">{{ item }}</view>',
'<block wx:for="{{list}}" wx:for-item="item" wx:for-index="__i0__"><view data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\'],[\'arr.\'+item+\'\']]]]]}}" bindtap="__e">{{item}}</view></block>'
)
assertCodegen(
'<view v-for="item in list" @click="test(arr[getVal(item)])">{{ item }}</view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="__i0__"><view data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\'],[\'arr.\'+item.m0+\'\']]]]]}}" bindtap="__e">{{item.$orig}}</view></block>',
'with(this){var l0=__map(list,function(item,__i0__){var $orig=__get_orig(item);var m0=getVal(item);return{$orig:$orig,m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="item in list" :data-val="getVal(item)" @click="test(arr[(item)])">{{ item }}</view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="__i0__"><view data-val="{{item.m0}}" data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\'],[\'arr.\'+item.$orig+\'\']]]]]}}" bindtap="__e">{{item.$orig}}</view></block>',
'with(this){var l0=__map(list,function(item,__i0__){var $orig=__get_orig(item);var m0=getVal(item);return{$orig:$orig,m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="item in list" @click.stop="test(item)">{{ item }}</view>',
'<block wx:for="{{list}}" wx:for-item="item" wx:for-index="__i0__"><view data-event-opts="{{[[\'tap\',[[\'test\',[\'$0\'],[[[\'list\',\'\',__i0__]]]]]]]}}" catchtap="__e">{{item}}</view></block>'
......
......@@ -13,7 +13,8 @@ const {
const {
getCode,
customize,
processMemberExpression
processMemberExpression,
replaceMemberExpression
} = require('../../../util')
const {
......@@ -124,18 +125,18 @@ function parseMethod (method, state) {
if (isForIndex(state.scoped, element)) {
return element
} else {
extraArrayElements.push(t.stringLiteral(
extraArrayElements.push(replaceMemberExpression(t.stringLiteral(
getExtraDataPath(getCode(processMemberExpression(element, state)),
methodName)
))
), state))
}
} else {
extraArrayElements.push(forExtra)
}
} else {
extraArrayElements.push(t.stringLiteral(
extraArrayElements.push(replaceMemberExpression(t.stringLiteral(
getExtraDataPath(getCode(processMemberExpression(element, state)), methodName)
))
), state))
}
return t.stringLiteral('$' + (extraArrayElements.length - 1))
} else if ( // +1=>1
......
const t = require('@babel/types')
const babelTraverse = require('@babel/traverse').default
const babelGenerate = require('@babel/generator').default
const babelTemplate = require('@babel/template').default
const uniI18n = require('@dcloudio/uni-cli-i18n')
const {
......@@ -139,7 +140,11 @@ function processMemberProperty (node, state) {
state.options.replaceCodes = {}
}
const identifier = '__$m' + (state.options.__m__++) + '__'
state.options.replaceCodes[identifier] = `'+${genCode(property, true)}+'`
const code = { property }
code.toString = function () {
return `'+${genCode(this.property, true)}+'`
}
state.options.replaceCodes[identifier] = code
if (state.computedProperty) {
state.computedProperty[identifier] = property
}
......@@ -149,6 +154,27 @@ function processMemberProperty (node, state) {
}
}
function replaceMemberExpression (stringLiteral, state) {
let code = `'${stringLiteral.value}'`
const replaceCodes = state.options.replaceCodes
if (replaceCodes) {
const options = {}
Object.keys(replaceCodes).forEach(key => {
const newCode = code.replace(new RegExp(key.replace('$', '\\$'), 'g'), `'+%%${key}%%+'`)
if (newCode !== code) {
options[key] = replaceCodes[key].property
code = newCode
}
})
const buildRequire = babelTemplate(code)
if (Object.keys(options).length) {
const ast = buildRequire(options)
return ast.expression
}
}
return stringLiteral
}
function processMemberExpression (element, state) {
// item['order']=>item.order
if (t.isMemberExpression(element)) {
......@@ -332,6 +358,7 @@ module.exports = {
return str
}),
processMemberExpression,
replaceMemberExpression,
getForIndexIdentifier,
isSimpleObjectExpression,
hasEscapeQuote,
......
......@@ -18,6 +18,7 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/parser": "^7.3.3",
"@babel/template": "^7.3.3",
"@babel/traverse": "^7.3.3",
"@babel/types": "^7.3.3",
"vue-template-compiler": "^2.6.10"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册