1. 程式人生 > 實用技巧 >VUE JSX基本常用語法

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!")])])}
}