basic event handling

This commit is contained in:
Evan You 2016-04-11 02:24:34 -04:00
parent d5c1c3a640
commit cc57e967f5

View File

@ -3,11 +3,11 @@ import { parseText } from './text-parser'
const bindRE = /^:|^v-bind:/
const onRE = /^@|^v-on:/
const mustUsePropsRE = /^(value|selected|checked|muted)$/
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/
export function generate (ast) {
const code = genElement(ast)
return new Function (`with (this) { return ${code}}`)
}
return new Function (`with (this) { return ${code}}`)}
function genElement (el, key) {
let exp
@ -18,12 +18,12 @@ function genElement (el, key) {
} else if (el.tag === 'template') {
return genChildren(el)
} else {
return `__h__('${ el.tag }', ${ genData(el, key) }, ${ genChildren(el) })`
return `__h__('${el.tag}', ${genData(el, key) }, ${genChildren(el)})`
}
}
function genIf (el, exp) {
return `(${ exp }) ? ${ genElement(el) } : ''`
return `(${exp}) ? ${genElement(el)} : ''`
}
function genFor (el, exp) {
@ -34,7 +34,7 @@ function genFor (el, exp) {
const alias = inMatch[1].trim()
exp = inMatch[2].trim()
const key = el.attrsMap['track-by'] || 'undefined'
return `(${ exp }).map(function (${ alias }, $index) {return ${ genElement(el, key) }})`
return `(${exp}).map(function (${alias}, $index) {return ${genElement(el, key) }})`
}
function genData (el, key) {
@ -43,40 +43,44 @@ function genData (el, key) {
}
let data = '{'
if (key) {
data += `key:${ key },`
data += `key:${key},`
}
if (el.attrsMap[':class']) {
data += `class: ${ el.attrsMap[':class'] },`
data += `class: ${el.attrsMap[':class']},`
}
if (el.attrsMap['class']) {
data += `staticClass: "${ el.attrsMap['class'] }"`
data += `staticClass: "${el.attrsMap['class']}"`
}
let attrs = `attrs:{`
let props = `props:{`
let events = `on:{`
let hasAttrs = false
let hasProps = false
let hasEvents = false
for (let i = 0, l = el.attrs.length; i < l; i++) {
let attr = el.attrs[i]
let name = attr.name
let value = attr.value
if (bindRE.test(name)) {
name = name.replace(bindRE, '')
if (name === 'class') {
continue
} else if (name === 'style') {
data += `style: ${ attr.value },`
data += `style: ${value},`
} else if (mustUsePropsRE.test(name)) {
hasProps = true
props += `"${ name }": (${ attr.value }),`
props += `"${name}": (${value}),`
} else {
hasAttrs = true
attrs += `"${ name }": (${ attr.value }),`
attrs += `"${name}": (${value}),`
}
} else if (onRE.test(name)) {
hasEvents = true
name = name.replace(onRE, '')
// TODO
events += genEvent(name, value)
} else if (name !== 'class') {
hasAttrs = true
attrs += `"${ name }": (${ JSON.stringify(attr.value) }),`
attrs += `"${name}": (${JSON.stringify(attr.value)}),`
}
}
if (hasAttrs) {
@ -85,6 +89,9 @@ function genData (el, key) {
if (hasProps) {
data += props.slice(0, -1) + '},'
}
if (hasEvents) {
data += events.slice(0, -1) + '},'
}
return data.replace(/,$/, '') + '}'
}
@ -116,6 +123,17 @@ function genText (text) {
}
}
function genEvent (name, value) {
// TODO support modifiers
if (!value) {
return `"${name}":function(){},`
} if (simplePathRE.test(value)) {
return `"${name}":${value},`
} else {
return `"${name}":function($event){${value}},`
}
}
function getAttr (el, attr) {
let val
if (val = el.attrsMap[attr]) {