提交 c8c1333b 编写于 作者: fxy060608's avatar fxy060608

Merge branch 'dev' of https://github.com/dcloudio/uni-app into dev

...@@ -126,7 +126,7 @@ module.exports = { ...@@ -126,7 +126,7 @@ module.exports = {
Identifier (path) { Identifier (path) {
const node = path.node const node = path.node
const name = node.name const name = node.name
if (names.includes(name) && path.key !== 'key' && path.key !== 'property' && !(path.scope && path.scope.hasBinding(name))) { if (names.includes(name) && path.key !== 'key' && (path.key !== 'property' || path.parent.computed) && !(path.scope && path.scope.hasBinding(name))) {
path.replaceWithSourceString(`${paramName}.${name}`) path.replaceWithSourceString(`${paramName}.${name}`)
} }
} }
......
...@@ -326,6 +326,12 @@ describe('mp:compiler', () => { ...@@ -326,6 +326,12 @@ describe('mp:compiler', () => {
'<input @input="onInput($event, 2+2);">', '<input @input="onInput($event, 2+2);">',
'<input data-event-opts="{{[[\'input\',[[\'onInput\',[\'$event\',2+2]]]]]}}" bindinput="__e"/>' '<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 // tricky symbols in args
// assertCodegen( // assertCodegen(
// `<input @input="onInput(');[\\'());');">`, // `<input @input="onInput(');[\\'());');">`,
......
...@@ -62,6 +62,7 @@ module.exports = { ...@@ -62,6 +62,7 @@ module.exports = {
VAR_FILTER: 'F', VAR_FILTER: 'F',
ATTR_DATA_EVENT_OPTS: 'data-event-opts', ATTR_DATA_EVENT_OPTS: 'data-event-opts',
ATTR_DATA_COM_TYPE: 'data-com-type', ATTR_DATA_COM_TYPE: 'data-com-type',
ATTR_DATA_EVENT_PARAMS: 'data-event-params',
INTERNAL_GET_ORIG, INTERNAL_GET_ORIG,
INTERNAL_GET_CLASS, INTERNAL_GET_CLASS,
INTERNAL_GET_STYLE, INTERNAL_GET_STYLE,
...@@ -120,4 +121,4 @@ module.exports = { ...@@ -120,4 +121,4 @@ module.exports = {
IDENTIFIER_STYLE: '__$$style$$__', IDENTIFIER_STYLE: '__$$style$$__',
IDENTIFIER_EVENT: '__$$event$$__', IDENTIFIER_EVENT: '__$$event$$__',
IDENTIFIER_GLOBAL: '__$$global$$__' IDENTIFIER_GLOBAL: '__$$global$$__'
} }
const t = require('@babel/types') const t = require('@babel/types')
const parser = require('@babel/parser')
const { const {
IDENTIFIER_EVENT, IDENTIFIER_EVENT,
VUE_EVENT_MODIFIERS, VUE_EVENT_MODIFIERS,
INTERNAL_EVENT_PROXY, INTERNAL_EVENT_PROXY,
ATTR_DATA_EVENT_OPTS, ATTR_DATA_EVENT_OPTS,
ATTR_DATA_EVENT_PARAMS,
INTERNAL_SET_SYNC INTERNAL_SET_SYNC
} = require('../../../constants') } = require('../../../constants')
...@@ -212,8 +214,9 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, ...@@ -212,8 +214,9 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
let isOnce = false let isOnce = false
const methods = [] const methods = []
const params = []
if (type) { if (type) {
isPassive = type.charAt(0) === VUE_EVENT_MODIFIERS.passive isPassive = type.charAt(0) === VUE_EVENT_MODIFIERS.passive
type = isPassive ? type.slice(1) : type type = isPassive ? type.slice(1) : type
...@@ -318,7 +321,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, ...@@ -318,7 +321,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
ReturnStatement (path) { ReturnStatement (path) {
const argument = path.node.argument const argument = path.node.argument
if (t.isCallExpression(argument)) { if (t.isCallExpression(argument)) {
if (t.isIdentifier(argument.callee)) { if (t.isIdentifier(argument.callee)) { // || t.isMemberExpression(argument.callee)
anonymous = false anonymous = false
parseEventByCallExpression(argument, methods) parseEventByCallExpression(argument, methods)
} }
...@@ -326,6 +329,27 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, ...@@ -326,6 +329,27 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
} }
}) })
if (anonymous) { 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' || path.parent.computed) && 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)) methods.push(addEventExpressionStatement(funcPath, state, isComponent, isNativeOn))
} }
} }
...@@ -334,6 +358,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, ...@@ -334,6 +358,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
return { return {
type, type,
params,
methods, methods,
modifiers: { modifiers: {
isCatch, isCatch,
...@@ -358,6 +383,7 @@ function _processEvent (path, state, isComponent, isNativeOn = false, tagName, r ...@@ -358,6 +383,7 @@ function _processEvent (path, state, isComponent, isNativeOn = false, tagName, r
const valuePath = propertyPath.get('value') const valuePath = propertyPath.get('value')
const { const {
type, type,
params,
methods, methods,
modifiers: { modifiers: {
isCatch, isCatch,
...@@ -393,12 +419,13 @@ function _processEvent (path, state, isComponent, isNativeOn = false, tagName, r ...@@ -393,12 +419,13 @@ function _processEvent (path, state, isComponent, isNativeOn = false, tagName, r
if (isCustom) { if (isCustom) {
optType = VUE_EVENT_MODIFIERS.custom + optType optType = VUE_EVENT_MODIFIERS.custom + optType
} }
opts.push( opts.push({
t.arrayExpression([ opt: t.arrayExpression([
t.stringLiteral(optType), t.stringLiteral(optType),
t.arrayExpression(methods) t.arrayExpression(methods)
]) ]),
) params
})
keyPath.replaceWith( keyPath.replaceWith(
t.stringLiteral( t.stringLiteral(
...@@ -422,15 +449,18 @@ module.exports = function processEvent (paths, path, state, isComponent, tagName ...@@ -422,15 +449,18 @@ module.exports = function processEvent (paths, path, state, isComponent, tagName
const ret = [] const ret = []
const opts = [] const opts = []
const params = []
if (onPath) { 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) opts.push(opt)
params.push(...array)
}) })
} }
if (nativeOnPath) { 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) opts.push(opt)
params.push(...array)
}) })
} }
if (!opts.length) { if (!opts.length) {
...@@ -444,5 +474,15 @@ module.exports = function processEvent (paths, path, state, isComponent, tagName ...@@ -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 return ret
} }
...@@ -4,15 +4,6 @@ function isMatch (name, forItem, forIndex) { ...@@ -4,15 +4,6 @@ function isMatch (name, forItem, forIndex) {
return name === forItem || name === forIndex return name === forItem || name === forIndex
} }
function getIdentifierName (element) {
if (t.isMemberExpression(element)) {
return getIdentifierName(element.object)
} else if (t.isCallExpression(element)) {
return getIdentifierName(element.callee)
}
return element.name && element.name.split('.')[0]
}
function findScoped (path, state) { function findScoped (path, state) {
if (!path) { if (!path) {
return state return state
...@@ -23,30 +14,17 @@ function findScoped (path, state) { ...@@ -23,30 +14,17 @@ function findScoped (path, state) {
forIndex forIndex
} = scoped } = scoped
let match = false let match = false
if (path.isIdentifier() || path.isMemberExpression()) { path.traverse({
match = isMatch(getIdentifierName(path.node), forItem, forIndex) noScope: true,
} else { Identifier (path) {
path.traverse({ if (!match && path.key !== 'key' && (path.key !== 'property' || path.parent.computed)) {
noScope: true, match = isMatch(path.node.name, forItem, forIndex)
Identifier (path) { if (match) {
if (!match) { path.stop()
match = isMatch(path.node.name, forItem, forIndex)
if (match) {
path.stop()
}
}
},
MemberExpression (path) {
if (!match) {
match = isMatch(getIdentifierName(path.node), forItem, forIndex)
if (match) {
path.stop()
}
path.skip()
} }
} }
}) }
} })
return match return match
}) })
if (!scoped && state.scoped.length > 1) { if (!scoped && state.scoped.length > 1) {
...@@ -75,4 +53,4 @@ module.exports = function getMemberExpr (path, name, init, state, variableDeclar ...@@ -75,4 +53,4 @@ module.exports = function getMemberExpr (path, name, init, state, variableDeclar
const contextIdentifier = t.identifier(scoped.context) const contextIdentifier = t.identifier(scoped.context)
contextIdentifier.$mpProcessed = true contextIdentifier.$mpProcessed = true
return t.memberExpression(contextIdentifier, identifier) return t.memberExpression(contextIdentifier, identifier)
} }
...@@ -132,7 +132,7 @@ function checkUsingGlobalComponents (name, globalUsingComponents, state) { ...@@ -132,7 +132,7 @@ function checkUsingGlobalComponents (name, globalUsingComponents, state) {
} }
module.exports = { module.exports = {
noScope: true, noScope: false,
MemberExpression (path) { MemberExpression (path) {
if ( // t.m(123) if ( // t.m(123)
t.isIdentifier(path.node.object) && t.isIdentifier(path.node.object) &&
......
...@@ -542,14 +542,17 @@ export function handleEvent (event) { ...@@ -542,14 +542,17 @@ export function handleEvent (event) {
} }
handler.once = true handler.once = true
} }
ret.push(handler.apply(handlerCtx, processEventArgs( const params = processEventArgs(
this.$vm, this.$vm,
event, event,
eventArray[1], eventArray[1],
eventArray[2], eventArray[2],
isCustom, isCustom,
methodName 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.
先完成此消息的编辑!
想要评论请 注册