VUE JSX基本常用語法
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!")])])}
}