VUE JSX基本常用语法
参考:https://github.com/vuejs/jsx
Content 内容
render() {
return <p>hello</p>
}
动态内容
render() {
return <p>hello { this.message }</p>
}
自闭合标签
render() {
return <input />
}
组件
import MyComponent from ‘./my-component‘
export default {
render() {
return <MyComponent>hello</MyComponent>
}
}
属性Attributes/Props
render() {
return <input type="email" />
}
动态绑定属性
render() {
return <input
type="email"
placeholder={this.placeholderText}
/>
}
使用延展操作符
render() {
const inputAttrs = {
type: ‘email‘,
placeholder: ‘Enter your email‘
}
return <input {...{ attrs: inputAttrs }} />
}
Slots插槽
命名插槽
render() {
return (
<MyComponent>
<header slot="header">header</header>
<footer slot="footer">footer</footer>
</MyComponent>
)
}
作用域插槽
render() {
const scopedSlots = {
header: () => <header>header</header>,
footer: () => <footer>footer</footer>
}
return <MyComponent scopedSlots={scopedSlots} />
}
Directives指令
<input vModel={this.newTodoText} />
使用修饰符
<input vModel_trim={this.newTodoText} />
使用参数
<input vOn:click={this.newTodoText} />
同时使用参数和修饰符
<input vOn:click_stop_prevent={this.newTodoText} />
v-html
<p domPropsInnerHTML={html}></p>
函数式组件
export default ({ props }) => <p>hello {props.message}</p>
const HelloWorld = ({ props }) => <p>hello {props.message}</p>
以下内容来自:
https://cn.vuejs.org/v2/guide/render-function.html#%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BB%84%E4%BB%B6
一个函数式组件就像这样:
Vue.component(‘my-component‘, {
functional: true,
props: {
// ...
},
render: function(createElement, context) {
// ...
}
})
当使用函数式组件时,该引用将会是HTMLElement,因为他们是无状态的也是无实例的。
在2.5.0及以上版本中,如果你使用了单文件组件,那么基于模板的函数式组件可以这样声明:
<template functional>
</template>
组件需要的一切都是通过context参数传递,它是一个包括如下字段的对象:
- props 提供所有prop的对象
- children VNode子节点的数组
- slots 一个函数,返回了包含所有插槽的对象
- scopedSlots (2.6.0) 一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽
- data 传递给组件的整个数据对象,作为createElement的第二个参数传入组件
- parent 对父组件的引用
- listeners (2.3.0+)一个包含了所有父组件为当前组件注册的事件监听器的对象。这是data.on的一个别名
- injections (2.3.0+)如果使用了inject选项,则该对象包含了应当被注入的property
因为函数式组件只是函数,所以渲染开销也低很多。
在作为包装组件时它们也同样非常有用。比如,当你需要做这些时:
- 程序化地在多个组件中选择一个来代为渲染;
- 在将children、props、data传递给子组件之前操作它们
下面是一个smart-list组件的例子,它能根据传入prop的值来代为渲染更具体的组件:
var EmptyList = { /* ... */ }
var TableList = { /* ... */ }
var OrderedList = { /* ... */ }
var UnorderedList = { /* ... */ }
Vue.component(‘smart-list‘, {
functional: true,
props: {
items: {
type: Array,
required: true
},
isOrdered: Boolean
},
render: function(createElement, context) {
function approproiateListComponent() {
var items = context.props.items
if(item.length === 0) return EmptyList;
if(typeof item[0] === ‘object‘) return TableList
if(context.props.isOrdered) return OrderedList
return UnorderedList
}
return createElement(
appropriateListComponent(),
context.data,
context.children
)
}
})
向子元素或子组件传递attribute和事件
在普通组件中,没有被定义为prop的attribute会自动添加到组件的根元素上,将已有的同名attributej进行替换或与其进行智能合并。
然而函数式组件要求你显示定义该行为:
Vue.component(‘my-functional-button‘, {
functional: true,
render: function(createElement, context) {
// 完全透传任何attribute、事件监听器、子节点等
return createElement(‘button‘, context.data, context.children)
}
})
如果你使用基于模板的函数式组件,那么你还需要手动添加attribute和监听器。因为我们可以访问到其独立的上下文内容,所以我们可以使用data.attrs传递任何HTML attribute,也可以使用listeners(即data.on的别名)传递任何事件监听器。
<template functional>
<button class="btn btn-primary" v-bind="data.attrs" v-on="listeners">
<slot />
</button>
</template>
slots()和children对比
你可能想知道为什么同时需要slots()和children。 slots().default不是和 children类似的吗?
在一些场景中,是这样,但如果是如下的带有子节点的函数式组件呢?
<my-functional-component>
<p v-slot:foo>
first
</p>
<p>second</p>
</my-functional-component>
对于这个组件,children会给你两个段落标签,而slots().default只会传递第二个匿名段落标签,slots().foo会传递第一个具名段落标签。同时拥有children和slots(),因此你可以选择让组件感知某个插槽机制,还是简单地通过传递children,移交给其他组件去处理。
模板编译
你可能会有兴趣知道,Vue的模板实际上被编译成了渲染函数。这是一个实现细节,通常不需要关心。但是如果你想看看模板的功能具体是怎样被编译的,可能会发现非常有意思。下面是一个使用Vue.compile来实时编译模板字符串的简单示例:
<div>
<header>
<h1>I‘m a template</h1>
</header>
<p v-if="message">{{ message }}</p>
<p v-else>No Message.</p>
</div>
render:
function anonymous () {
with(this){return _c(‘div‘,[_m(0), (message)?_c(‘p‘, [_V(_s(message))]):_c(‘p‘,[_v("No message.")])])}
}
_m(0): function anonymous() {
with(this){return _c(‘header‘, [_c(‘h1‘,[_v("I‘m a template!")])])}
}