remove <render> tag

This commit is contained in:
Evan You 2016-06-17 13:25:34 -04:00
parent d398023ad1
commit e3fb6fe834
6 changed files with 3 additions and 218 deletions

View File

@ -84,10 +84,6 @@ declare type ASTElement = {
ref?: string,
refInFor?: boolean,
render?: true,
renderMethod?: ?string,
renderArgs?: ?string,
if?: string,
ifProcessed?: boolean,
else?: true,

View File

@ -45,8 +45,6 @@ function genElement (el: ASTElement): string {
return genIf(el)
} else if (el.tag === 'template' && !el.slotTarget) {
return genChildren(el) || 'void 0'
} else if (el.tag === 'render') {
return genRender(el)
} else if (el.tag === 'slot') {
return genSlot(el)
} else {
@ -245,18 +243,6 @@ function genText (text: ASTText | ASTExpression): string {
: '_t(' + JSON.stringify(text.text) + ')'
}
function genRender (el: ASTElement): string {
if (!el.renderMethod) {
return 'void 0'
}
const children = genChildren(el)
return `${el.renderMethod}(${
el.renderArgs || ''
}${
children ? (el.renderArgs ? ',' : '') + children : ''
})`
}
function genSlot (el: ASTElement): string {
const slot = `$slots[${el.slotName || '"default"'}]`
const children = genChildren(el)

View File

@ -123,7 +123,6 @@ export function parse (
// determine whether this is a plain element after
// removing if/for/once attributes
element.plain = !element.key && !attrs.length
processRender(element)
processSlot(element)
processComponent(element)
for (let i = 0; i < transforms.length; i++) {
@ -145,8 +144,8 @@ export function parse (
}
if (element.attrsMap.hasOwnProperty('v-for')) {
warn(
'Cannot use v-for on component root element because it renders ' +
'multiple elements:\n' + template
'Cannot use v-for on stateful component root element because ' +
'it renders multiple elements:\n' + template
)
}
}
@ -306,24 +305,6 @@ function processOnce (el) {
}
}
function processRender (el) {
if (el.tag === 'render') {
el.render = true
el.renderMethod = el.attrsMap[':method'] || el.attrsMap['v-bind:method']
el.renderArgs = el.attrsMap[':args'] || el.attrsMap['v-bind:args']
if (process.env.NODE_ENV !== 'production') {
if (el.attrsMap.method) {
warn('<render> method should use a dynamic binding, e.g. `:method="..."`.')
} else if (!el.renderMethod) {
warn('method attribute is required on <render>.')
}
if (el.attrsMap.args) {
warn('<render> args should use a dynamic binding, e.g. `:args="..."`.')
}
}
}
}
function processSlot (el) {
if (el.tag === 'slot') {
el.slotName = getBindingAttr(el, 'name')

View File

@ -1,134 +0,0 @@
import Vue from 'vue'
describe('Render', () => {
it('render with basic usage', () => {
const vm = new Vue({
template: `<div><render :method="onRender" :args="'hello'"></render></div>`,
methods: {
onRender (args) { return args }
}
}).$mount()
expect(vm.$el.tagName).toBe('DIV')
expect(vm.$el.innerHTML).toBe('hello')
})
it('should render with $createElement', () => {
const vm = new Vue({
template: `<div><render :method="onRender" :args="message"></render></div>`,
data: { message: 'hello world' },
methods: {
onRender (args) {
const h = this.$createElement
return h('div', { class: 'message' }, [
h('p', {}, [args])
])
}
}
}).$mount()
expect(vm.$el.childNodes[0].tagName).toBe('DIV')
expect(vm.$el.childNodes[0]).toHaveClass('message')
expect(vm.$el.childNodes[0].childNodes[0].tagName).toBe('P')
expect(vm.$el.childNodes[0].childNodes[0].textContent).toBe('hello world')
})
it('should render with inline elements', () => {
const vm = new Vue({
template: `
<render :method="onRender" :args="message">
<ul>
<li v-for="n in 5"></li>
</ul>
</render>
`,
data: { message: 'hello world' },
methods: {
onRender (args, children) {
const ul = children[0]
ul.children.forEach((li, i) => {
li.data = { staticClass: `class${i}` }
})
return ul
}
}
}).$mount()
const ul = vm.$el
expect(ul.tagName).toBe('UL')
for (let i = 0; i < ul.children.length; i++) {
const li = ul.children[i]
expect(li.tagName).toBe('LI')
expect(li).toHaveClass(`class${i}`)
}
})
it('should render component', done => {
const modal = {
template: `
<div class="modal-container">
<div class="modal-header">
<h1 class="modal-title">{{title}}</h1>
</div>
<div class="modal-body">
<slot name="body">default body</slot>
</div>
<div class="modal-footer">
<button class="modal-action-close" @click="$emit('close')">close</div>
</div>
</div>
`,
props: {
title: {
type: String, default: 'title1'
}
}
}
const vm = new Vue({
template: `<div><render :method="onRenderModal" :args="title"></render></div>`,
data: {
shown: true,
title: 'hello modal'
},
components: { modal },
methods: {
onRenderModal (title) {
return this.$createElement('modal', {
props: { title: title },
on: { close: this.onCloseModal },
directives: [{ name: 'show', value: this.shown }]
})
},
onCloseModal () { this.shown = false }
}
}).$mount()
expect(vm.$el.querySelector('.modal-title').textContent).toBe(vm.title)
vm.$el.querySelector('.modal-action-close').click()
waitForUpdate(() => {
expect(vm.shown).toBe(false)
}).then(() => {
expect(vm.$el.querySelector('.modal-container').style.display).toBe('none')
}).then(done)
})
it('should warn no method', () => {
new Vue({
template: '<render></render>'
}).$mount()
expect('method attribute is required on <render>').toHaveBeenWarned()
})
it('should warn method/arg usage without v-bind', () => {
new Vue({
template: '<render method="a"></render>'
}).$mount()
expect('<render> method should use a dynamic binding').toHaveBeenWarned()
})
it('should warn non dynamic args', () => {
new Vue({
template: '<render :method="a" args="b"></render>',
methods: {
a: () => {}
}
}).$mount()
expect('<render> args should use a dynamic binding').toHaveBeenWarned()
})
})

View File

@ -113,28 +113,6 @@ describe('codegen', () => {
)
})
it('generate render tag', () => {
assertCodegen(
'<render :method="onRender" :args="params"></render>',
`with(this){return onRender(params)}`
)
})
it('generate render tag that have children', () => {
assertCodegen(
'<render :method="onRender"><p>hello</p></render>',
`with(this){return onRender([_m(0)])}`,
[`with(this){return _h(_e('p'),[_t("hello")])}`]
)
})
it('generate render tag with `method` is not dynamic binding', () => {
assertCodegen(
'<render method="onRender"></render>',
`with(this){return void 0}`
)
})
it('generate single slot', () => {
assertCodegen(
'<slot></slot>',

View File

@ -89,7 +89,7 @@ describe('parser', () => {
it('warn v-for on root element', () => {
parse('<div v-for="item in items"></div>', baseOptions)
expect('Cannot use v-for on component root element').toHaveBeenWarned()
expect('Cannot use v-for on stateful component root element').toHaveBeenWarned()
})
it('v-pre directive', () => {
@ -162,28 +162,6 @@ describe('parser', () => {
expect(ast.once).toBe(true)
})
it('render tag syntax', () => {
const ast = parse('<render :method="onRender", :args="params"></render>', baseOptions)
expect(ast.render).toBe(true)
expect(ast.renderMethod).toBe('onRender')
expect(ast.renderArgs).toBe('params')
})
it('render tag invalid syntax', () => {
// method nothing
const invalidAst1 = parse('<render></render>', baseOptions)
expect('method attribute is required on <render>.').toHaveBeenWarned()
expect(invalidAst1.render).toBe(true)
expect(invalidAst1.renderMethod).toBeUndefined()
expect(invalidAst1.renderArgs).toBeUndefined()
// method no dynamic binding
parse('<render method="onRender"></render>', baseOptions)
expect('<render> method should use a dynamic binding').toHaveBeenWarned()
// args no dynamic binding
parse('<render :method="onRender" args="params"></render>', baseOptions)
expect('<render> args should use a dynamic binding').toHaveBeenWarned()
})
it('slot tag single syntax', () => {
const ast = parse('<slot></slot>', baseOptions)
expect(ast.tag).toBe('slot')