diff --git a/packages/uni-template-compiler/__tests__/compiler-extra.spec.js b/packages/uni-template-compiler/__tests__/compiler-extra.spec.js
index 71c08eb11b84d1d65a498b21c8490c6afbe3d133..7238037e808bf9ac48d39eaf995f71a264743665 100644
--- a/packages/uni-template-compiler/__tests__/compiler-extra.spec.js
+++ b/packages/uni-template-compiler/__tests__/compiler-extra.spec.js
@@ -584,7 +584,12 @@ describe('mp:compiler-extra', () => {
``
)
})
- it('generate event ', () => {
+ it('generate event ', () => {
+ assertCodegen(
+ ``,
+ ``
+ )
+
assertCodegen(
`{{item.title}}`,
`{{item.title}}`
diff --git a/packages/uni-template-compiler/__tests__/demo.js b/packages/uni-template-compiler/__tests__/demo.js
index cfca7bbdc6798af3c887323f1b7ce7eb02a79382..7ead891078114e8cafa93cfb04a25e33fc90f5fb 100644
--- a/packages/uni-template-compiler/__tests__/demo.js
+++ b/packages/uni-template-compiler/__tests__/demo.js
@@ -2,7 +2,7 @@ const compiler = require('../lib')
const res = compiler.compile(
`
-
+
`, {
resourcePath: '/User/fxy/Documents/test.wxml',
mp: {
diff --git a/packages/uni-template-compiler/lib/index.js b/packages/uni-template-compiler/lib/index.js
index 9e6b3cd5e442dc08dbf808c53679e7fcb90a01c0..084a219726b34d494ef21c575b60330f2d483172 100644
--- a/packages/uni-template-compiler/lib/index.js
+++ b/packages/uni-template-compiler/lib/index.js
@@ -55,10 +55,18 @@ module.exports = {
}
// console.log(`function render(){${res.render}}`)
const ast = parser.parse(`function render(){${res.render}}`)
-
- res.render = generateScript(traverseScript(ast, state), state)
-
- let template = generateTemplate(traverseTemplate(ast, state), state)
+ let template = ''
+
+ try {
+ res.render = generateScript(traverseScript(ast, state), state)
+ template = generateTemplate(traverseTemplate(ast, state), state)
+ } catch (e) {
+ console.error(e)
+ throw new Error('Compile failed at ' + options.resourcePath.replace(
+ path.extname(options.resourcePath),
+ '.vue'
+ ))
+ }
res.specialMethods = state.options.specialMethods || new Set()
delete state.options.specialMethods
diff --git a/packages/uni-template-compiler/lib/script/traverse/data/event.js b/packages/uni-template-compiler/lib/script/traverse/data/event.js
index 22ec016c584cf90780417d629f5fe469ff97f179..8efef87e721aed53bf09e2294987c6f1d8afaa3e 100644
--- a/packages/uni-template-compiler/lib/script/traverse/data/event.js
+++ b/packages/uni-template-compiler/lib/script/traverse/data/event.js
@@ -167,7 +167,7 @@ function getMethodName (methodName) {
return methodName === '__HOLDER__' ? '' : methodName
}
-function parseEventByCallExpression (callExpr, methods) {
+function parseEventByCallExpression (callExpr, methods) {
let methodName = callExpr.callee.name
if (methodName === '$set') {
methodName = INTERNAL_SET_SYNC
@@ -197,12 +197,12 @@ function parseEventByCallExpression (callExpr, methods) {
arrayExpression.push(t.arrayExpression(argsExpression))
}
}
- methods.push(t.arrayExpression(arrayExpression))
+ methods.push(t.arrayExpression(arrayExpression))
}
function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, tagName, ret) {
const key = keyPath.node
- let type = key.value || key.name
+ let type = key.value || key.name || ''
const isCustom = isComponent && !isNativeOn
@@ -211,124 +211,126 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
let isPassive = false
let isOnce = false
- isPassive = type.charAt(0) === VUE_EVENT_MODIFIERS.passive
- type = isPassive ? type.slice(1) : type
+ let methods = []
- isOnce = type.charAt(0) === VUE_EVENT_MODIFIERS.once // Prefixed last, checked first
- type = isOnce ? type.slice(1) : type
+ if (type) {
+ isPassive = type.charAt(0) === VUE_EVENT_MODIFIERS.passive
+ type = isPassive ? type.slice(1) : type
- isCapture = type.charAt(0) === VUE_EVENT_MODIFIERS.capture
- type = isCapture ? type.slice(1) : type
+ isOnce = type.charAt(0) === VUE_EVENT_MODIFIERS.once // Prefixed last, checked first
+ type = isOnce ? type.slice(1) : type
- const specialEvents = state.options.platform.specialEvents
- const isSpecialEvent = specialEvents[tagName] && Object.keys(specialEvents[tagName]).includes(type)
+ isCapture = type.charAt(0) === VUE_EVENT_MODIFIERS.capture
+ type = isCapture ? type.slice(1) : type
- let methods = []
+ const specialEvents = state.options.platform.specialEvents
+ const isSpecialEvent = specialEvents[tagName] && Object.keys(specialEvents[tagName]).includes(type)
- if (!valuePath.isArrayExpression()) {
- valuePath = [valuePath]
- } else {
- valuePath = valuePath.get('elements')
- }
+ if (!valuePath.isArrayExpression()) {
+ valuePath = [valuePath]
+ } else {
+ valuePath = valuePath.get('elements')
+ }
- valuePath.forEach(funcPath => {
- if ( // wxs event
- funcPath.isMemberExpression() &&
- t.isIdentifier(funcPath.node.object) &&
- state.options.filterModules.includes(funcPath.node.object.name)
- ) {
- const {
- getEventType,
- formatEventType
- } = state.options.platform
- const wxsEventType = formatEventType(getEventType(type))
- if (key.value) {
- key.value = wxsEventType
- } else {
- key.name = wxsEventType
- }
- } else if (funcPath.isIdentifier()) { // on:{click:handle}
- if (!isSpecialEvent) {
- const arrayExpression = [t.stringLiteral(getMethodName(funcPath.node.name))]
- if (!isCustom) { // native events
- arrayExpression.push(defaultArgs)
+ valuePath.forEach(funcPath => {
+ if ( // wxs event
+ funcPath.isMemberExpression() &&
+ t.isIdentifier(funcPath.node.object) &&
+ state.options.filterModules.includes(funcPath.node.object.name)
+ ) {
+ const {
+ getEventType,
+ formatEventType
+ } = state.options.platform
+ const wxsEventType = formatEventType(getEventType(type))
+ if (key.value) {
+ key.value = wxsEventType
+ } else {
+ key.name = wxsEventType
}
- methods.push(t.arrayExpression(arrayExpression))
- } else {
- if (!state.options.specialMethods) {
- state.options.specialMethods = new Set()
+ } else if (funcPath.isIdentifier()) { // on:{click:handle}
+ if (!isSpecialEvent) {
+ const arrayExpression = [t.stringLiteral(getMethodName(funcPath.node.name))]
+ if (!isCustom) { // native events
+ arrayExpression.push(defaultArgs)
+ }
+ methods.push(t.arrayExpression(arrayExpression))
+ } else {
+ if (!state.options.specialMethods) {
+ state.options.specialMethods = new Set()
+ }
+ state.options.specialMethods.add(funcPath.node.name)
}
- state.options.specialMethods.add(funcPath.node.name)
- }
- } else if (isSpecialEvent) {
- state.errors.add(
- `${tagName} 组件 ${type} 事件仅支持 @${type}="methodName" 方式绑定`
- )
- } else if (funcPath.isArrowFunctionExpression()) { // e=>count++
- methods.push(addEventExpressionStatement(funcPath, state, isCustom))
- } else {
- let anonymous = true
+ } else if (isSpecialEvent) {
+ state.errors.add(
+ `${tagName} 组件 ${type} 事件仅支持 @${type}="methodName" 方式绑定`
+ )
+ } else if (funcPath.isArrowFunctionExpression()) { // e=>count++
+ methods.push(addEventExpressionStatement(funcPath, state, isCustom))
+ } else {
+ let anonymous = true
- // "click":function($event) {click1(item);click2(item);}
- const body = funcPath.node.body.body
- if (body.length) {
- const exprStatements = body.filter(node => {
- return t.isExpressionStatement(node) && t.isCallExpression(node.expression)
- })
- if (exprStatements.length === body.length) {
- anonymous = false
- exprStatements.forEach(exprStatement => {
- parseEventByCallExpression(exprStatement.expression, methods)
+ // "click":function($event) {click1(item);click2(item);}
+ const body = funcPath.node.body.body
+ if (body.length) {
+ const exprStatements = body.filter(node => {
+ return t.isExpressionStatement(node) && t.isCallExpression(node.expression)
})
- }
- }
-
- anonymous && funcPath.traverse({
- noScope: true,
- MemberExpression (path) {
- if (path.node.object.name === '$event' && path.node.property.name ===
- 'stopPropagation') {
- isCatch = true
- path.stop()
- }
- },
- AssignmentExpression (path) { // "update:title": function($event) {title = $event}
- const left = path.node.left
- const right = path.node.right
- // v-bind:title.sync="title"
- if (t.isIdentifier(left) &&
- t.isIdentifier(right) &&
- right.name === '$event' &&
- type.indexOf('update:') === 0) {
- methods.push(t.arrayExpression( // ['$set',['title','$event']]
- [
- t.stringLiteral(INTERNAL_SET_SYNC),
- t.arrayExpression([
- t.identifier(left.name),
- t.stringLiteral(left.name),
- t.stringLiteral('$event')
- ])
- ]
- ))
+ if (exprStatements.length === body.length) {
anonymous = false
- path.stop()
+ exprStatements.forEach(exprStatement => {
+ parseEventByCallExpression(exprStatement.expression, methods)
+ })
}
- },
- ReturnStatement (path) {
- const argument = path.node.argument
- if (t.isCallExpression(argument)) {
- if (t.isIdentifier(argument.callee)) {
+ }
+
+ anonymous && funcPath.traverse({
+ noScope: true,
+ MemberExpression (path) {
+ if (path.node.object.name === '$event' && path.node.property.name ===
+ 'stopPropagation') {
+ isCatch = true
+ path.stop()
+ }
+ },
+ AssignmentExpression (path) { // "update:title": function($event) {title = $event}
+ const left = path.node.left
+ const right = path.node.right
+ // v-bind:title.sync="title"
+ if (t.isIdentifier(left) &&
+ t.isIdentifier(right) &&
+ right.name === '$event' &&
+ type.indexOf('update:') === 0) {
+ methods.push(t.arrayExpression( // ['$set',['title','$event']]
+ [
+ t.stringLiteral(INTERNAL_SET_SYNC),
+ t.arrayExpression([
+ t.identifier(left.name),
+ t.stringLiteral(left.name),
+ t.stringLiteral('$event')
+ ])
+ ]
+ ))
anonymous = false
- parseEventByCallExpression(argument, methods)
+ path.stop()
+ }
+ },
+ ReturnStatement (path) {
+ const argument = path.node.argument
+ if (t.isCallExpression(argument)) {
+ if (t.isIdentifier(argument.callee)) {
+ anonymous = false
+ parseEventByCallExpression(argument, methods)
+ }
}
}
+ })
+ if (anonymous) {
+ methods.push(addEventExpressionStatement(funcPath, state, isComponent, isNativeOn))
}
- })
- if (anonymous) {
- methods.push(addEventExpressionStatement(funcPath, state, isComponent, isNativeOn))
}
- }
- })
+ })
+ }
return {
type,
@@ -345,6 +347,10 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
function _processEvent (path, state, isComponent, isNativeOn = false, tagName, ret) {
const opts = []
+ // remove invalid event
+ path.node.value.properties = path.node.value.properties.filter(property => {
+ return property.key.value || property.key.name
+ })
const len = path.node.value.properties.length
for (let i = 0; i < len; i++) {
const propertyPath = path.get(`value.properties.${i}`)
@@ -439,4 +445,4 @@ module.exports = function processEvent (paths, path, state, isComponent, tagName
)
return ret
-}
+}