Vue render 函數和JSX語法的使用

基本使用編程

Vue 推薦在絕大多數狀況下使用模板來建立你的 HTML。然而在一些場景中,你真的須要 JavaScript 的徹底編程的能力。這時你能夠用渲染函數,它比模板更接近編譯器。app

讓咱們深刻一個簡單的例子,這個例子裏 render 函數很實用。假設咱們要根據父組件傳過來的數據決定顯示哪一個標籤:dom

父組件:函數

<template>
  <div id="app">
    <level type="1">hello world</level>
    <level type="2">hello world</level>
    <level type="3">hello world</level>
    <level type="4">hello world</level>
  </div>
</template>

<script> import Level from './components/Level' export default { name: 'App', components: { Level } } </script>

Level組件:this

<template>
    <div>
        <h1 v-if="type == 1"><slot></slot></h1>
        <h2 v-else-if="type == 2"><slot></slot></h2>
        <h3 v-else-if="type == 3"><slot></slot></h3>
        <h4 v-else-if="type == 4"><slot></slot></h4>
    </div>
</template>
<script> export default { name: 'Level', props:{ type: String || Number } } </script>

Level組件根據父組件穿過來的type來判斷顯示h一、h二、h3等標籤,v-if 能夠說用到了"極致",並且寫了不少個冗餘的slotspa

使用render函數和JSX語法來改寫上面code

Level.js文件component

export default { props:{ type: String | Number }, methods:{ handleClick(e){ console.log(e.target) }, }, data(){ return {msg:'zf'} }, render(h){ //運行時
        // h('h' + this.type,{},[this.$slots.default])
        let tag = 'h' + this.type return <tag>
            <span value={tag} onClick={this.handleClick}>{this.$slots.default}</span>
            {this.msg} </tag>
 } }

省去了不少冗餘代碼,頁面一下清爽了不少orm

用JSX語法實現v-model、v-if、v-for語法blog

v-model:

export default { methods:{ handleInput(e){ this.msg = e.target.value } }, data(){ return {msg:'zf'} }, render(){ //運行時return {/* 實現v-model */} <input type="text" value={ this.msg} onInput={this.handleInput}></input>
            {this.msg} } }

給input框頂一個value屬性 一個input事件onInput,傳值和監聽事件改變值。

v-if: 三元表達式

render(){ return ( <div> {this.show?'好':'很差'} </div>
 ) }

簡單的語法能夠用三元表達式

複雜的語法仍是要用if/else來判斷

render(){ let ifText if(this.show){ ifText=<p>好</p>
        }else { ifText=<p>很差</p>
 } return ( <div> {ifText} </div>
 ) }

v-for:以menu菜單爲例

import elMenu from "./el-menu"; import elMenuItem from "./el-menu-item"; import elSubmenu from "./el-submenu"; export default { //父組件傳過來的數據
 props:{ data:{ type: Array, default:() => {} } }, data(){ return { menudata:[ {title: '根1', id: 1}, {title: '根2', id: 2, children: [ { title:'根2-1', id: 21, children: [ {title: '根2-1-1', id: 211}, {title: '根2-1-2', id: 212} ] } ] }, {title: '根3', id: 3}, {title: '根4', id: 4,children: [ {title: '根4-1', id: 41} ]} ] } }, render() { let renderChildren = (data) => { return data.map(child =>{ return child.children ? //判斷是否有孩子
                //有孩子渲染elSubmenu
                <elSubmenu> 
                    <div slot="title">{child.title}</div>
 {renderChildren(child.renderChildren)} </elSubmenu> : //沒有孩子渲染elMenuItem
                <elMenuItem></elMenuItem>
 }) } return <elMenu> {/* 循環遍歷孩子 顯示哪個 */} {renderChildren(this.data)} </elMenu>
 } }

 用自定義組件

導入進來,不用再在components屬性聲明瞭,直接寫在jsx中

<script> import HelloWolrd from './HelloWorld' export default { name: "item", render(){ return ( <HelloWolrd/>
 ) } } </script>

事件,class,style,ref等的綁定方式

render (h) { return ( <div // normal attributes or component props.
   id="foo"
   // DOM properties are prefixed with `domProps`
   domPropsInnerHTML="bar"
   // event listeners are prefixed with `on` or `nativeOn`
   onClick={this.clickHandler} nativeOnClick={this.nativeClickHandler} // other special top-level properties
   class={{ foo: true, bar: false }} style={{ color: 'red', fontSize: '14px' }} key="key" ref="ref"
   // assign the `ref` is used on elements/components with v-for
 refInFor slot="slot">
  </div>
 ) }

上面有個地方須要注意,當給自定義組件綁定事件時用nativeOnClick,而模板格式是用@click.native

 在實際開發中並非所有都有renderJSX語法好或者全都用template好,而是在須要的地方二者結合使用,效果會更好。

相關文章
相關標籤/搜索