support inline-template

This commit is contained in:
Evan You 2016-04-29 14:29:36 -04:00
parent 6d889c0116
commit b66be950f5
4 changed files with 50 additions and 15 deletions

View File

@ -1,26 +1,32 @@
import { genHandlers } from './events'
import { ref } from './directives/ref'
import { baseWarn } from './helpers'
const baseDirectives = {
ref,
cloak: function () {} // noop
}
// platform-injected utils
// configurable state
let warn
let platformDirectives
let isPlatformReservedTag
// reset on each call
let staticRenderFns
let currentOptions
export function generate (ast, options) {
staticRenderFns = []
// save previous staticRenderFns so generate calls can be nested
const prevStaticRenderFns = staticRenderFns
const currentStaticRenderFns = staticRenderFns = []
currentOptions = options
warn = options.warn || baseWarn
platformDirectives = options.directives || {}
isPlatformReservedTag = options.isReservedTag || (() => false)
const code = ast ? genElement(ast) : '__h__("div")'
staticRenderFns = prevStaticRenderFns
return {
render: `with (this) { return ${code}}`,
staticRenderFns
staticRenderFns: currentStaticRenderFns
}
}
@ -40,8 +46,11 @@ function genElement (el) {
} else {
// if the element is potentially a component,
// wrap its children as a thunk.
const children = genChildren(el, !isPlatformReservedTag(el.tag) /* asThunk */)
const code = `__h__('${el.tag}', ${genData(el)}, ${children}, '${el.ns || ''}')`
const children = el.inlineTemplate
? 'undefined'
: genChildren(el, !isPlatformReservedTag(el.tag) /* asThunk */)
const namespace = el.ns ? `,'${el.ns}'` : ''
const code = `__h__('${el.tag}', ${genData(el)}, ${children}${namespace})`
if (el.staticRoot) {
// hoist static sub-trees out
staticRenderFns.push(`with(this){return ${code}}`)
@ -138,7 +147,21 @@ function genData (el) {
}
// event handlers
if (el.events) {
data += genHandlers(el.events)
data += `${genHandlers(el.events)},`
}
// inline-template
if (el.inlineTemplate) {
if (process.env.NODE_ENV !== 'production' && (
el.children.length > 1 || !el.children[0].tag
)) {
warn('Inline-template components must have exactly one child element.')
}
const inlineRenderFns = generate(el.children[0], currentOptions)
data += `inlineTemplate:{render:function(){${
inlineRenderFns.render
}},staticRenderFns:[${
inlineRenderFns.staticRenderFns.map(code => `function(){${code}}`).join(',')
}]}`
}
return data.replace(/,$/, '') + '}'
}

View File

@ -1,5 +1,9 @@
import { isArray } from 'shared/util'
export function baseWarn (msg) {
console.error(`[Vue parser]: ${msg}`)
}
export function addProp (el, name, value) {
(el.props || (el.props = [])).push({ name, value })
}

View File

@ -9,7 +9,8 @@ import {
addStaticAttr,
addHandler,
addDirective,
getBindingAttr
getBindingAttr,
baseWarn
} from '../helpers'
const dirRE = /^v-|^@|^:/
@ -23,11 +24,8 @@ const camelRE = /[a-z\d][A-Z]/
const decodeHTMLCached = cached(decodeHTML)
// make warning customizable depending on environment.
// configurable state
let warn
const baseWarn = msg => console.error(`[Vue parser]: ${msg}`)
// other configurable options
let platformGetTagNamespace
let platformMustUseProp
let delimiters
@ -295,6 +293,9 @@ function processComponent (el) {
if (el.tag === 'component') {
el.component = getBindingAttr(el, 'is')
}
if (getAndRemoveAttr(el, 'inline-template') != null) {
el.inlineTemplate = true
}
}
function processClassBinding (el) {

View File

@ -67,13 +67,20 @@ export function createComponent (Ctor, data, parent, children, context) {
function init (vnode) {
const { Ctor, propsData, listeners, parent, children } = vnode.componentOptions
const child = new Ctor({
const options = {
parent,
propsData,
_parentVnode: vnode,
_parentListeners: listeners,
_renderChildren: children
})
}
// check inline-template render functions
const inlineTemplate = vnode.data.inlineTemplate
if (inlineTemplate) {
options.render = inlineTemplate.render
options.staticRenderFns = inlineTemplate.staticRenderFns
}
const child = new Ctor(options)
// if this is a server-rendered mount,
// the vnode would already have an element.
// otherwise the child sets the parent vnode's elm when mounted