vue之Render函數


(1)什么是Render函數

    先來看一個場景,在博客網中,一般有一級標題、二級標題、三級標題...,為了方便分享url,它們都做成了錨點,點擊后,會將內容加載網址后面,以#分隔。

    例如‘特性’是一個<h2>標簽,內容含有一個<a href='#特性'>#</a>的鏈接,點擊后url便帶有了錨點信息,別人打開時會直接聚焦到‘特性’所在的位置。如果將其封裝成一個組件,一般寫法會這樣:

<div id="app">
  <app-demo :level="level" title="特性">
    特性{{level}}
  </app-demo>
</div>
<script>
  Vue.component('app-demo',{
    template:`
              <div>
                <h1 v-if="level === 1">
                  <a :href=" '#' + title ">
                    <slot></slot>
                  </a>
                </h1>
                <h2 v-if="level === 2">
                  <a :href=" '#' + title ">
                    <slot></slot>
                  </a>
                </h2>
                <h3 v-if="level === 3">
                  <a :href=" '#' + title ">
                    <slot></slot>
                  </a>
                </h3>
                <h4 v-if="level === 4">
                  <a :href=" '#' + title ">
                    <slot></slot>
                  </a>
                </h4>
                <h5 v-if="level === 5">
                  <a :href=" '#' + title ">
                    <slot></slot>
                  </a>
                </h5>
                <h6 v-if="level === 6">
                  <a :href=" '#' + title ">
                    <slot></slot>
                  </a>
                </h6>
              </div>
            `,
    props:{
      level:{
        type:Number,
        require:true
      },
      title:{
        type:String,
        default:''
      }
    }
  });
  var app = new Vue({
    el:'#app',
    data:{
      level:2
    }
  });
</script>

效果:

    分析:這樣寫沒有什么錯誤,只是缺點太明顯,代碼冗長,組件的template代碼大多都是重復的,只是heading標題元素的級別不同,再者必須插入一個根元素<div>,這是組件的要求。

    template寫法在大多數時候很好用,但這里有些別扭。我們更像按照拼接字符串的形式來構造heading元素,比如"h"+this.leavel。在Render函數可以這樣做。

<div id="app">
  <app-demo :level="level" title="特性">
    特性{{level}}
  </app-demo>
</div>
<script>
  Vue.component('app-demo',{
    props:{
      level:{
        type:Number,
        require:true
      },
      title:{
        type:String,
        default:''
      }
    },
    render(createElement){
      return createElement(
        'h'+this.level,
        [
          createElement(
            'a',{
              domProps:{
                href:'#'+this.title
              }
            },
            this.$slots.default
          )
        ]
      )
    }
  });
  var app = new Vue({
    el:'#app',
    data:{
      level:2
    }
  });
</script>

    Render函數通過createElement參數來創建Virtual Dom虛擬Dom,結構精簡了很多。

 

(2)CreateElement用法 

    ①基本參數

    CreateElement構成了Vue虛擬Dom的模板,它有3個參數:第一個參數是必選的,可以是HTML標簽、組件、函數;第二個是可選的數據對象,在template使用;第三個是子節點,也是可選參數,用法一致。

    以往在template里,我們都是在組件的標簽上使用形容v-bind:class、v-bind:style額、v-on:click等這樣的指令。到Render函數后,都將其寫到了數據對象里,比如下面的組件,使用傳統的template寫法為

<div id="app">
  <ele></ele>
</div>
<script>
  Vue.component('ele',{
    template:`
      <div id="element" v-bind:class="{show:show}" v-on:click="handleClick">
        文本內容
      </div>
    `,
    data(){
      return {
        show:true
      }
    },
    methods:{
      handleClick:function(){
        console.log('您點擊了')
      }
    }
  });
  var app = new Vue({
    el:'#app'
  });
</script>

 使用Render改寫后的代碼為

<div id="app">
  <ele></ele>
</div>
<script>
  Vue.component('ele',{
    /*
    template:`
      <div id="element" v-bind:class="{show:show}" v-on:click="handleClick">
        文本內容
      </div>
    `,
     */
    render:function(createElement){
      return createElement(
        'div',/* 第一個參數是必選的,可以是HTML標簽、組件、函數*/
        {
            /*第二個是可選的數據對象,在template使用*/
            /*1、動態綁定class,等價於:class*/
            class:{
              'show':this.show
            },
            /* 2、普通HTML特性 */
            attrs:{
              id:'element'
            },
            /* 3、給div綁定click點擊事件 */
            on:{
              click:this.handleClick
            }
        },
        '文本內容'/*第三個是子節點,也是可選參數*/
      )
    },
    data(){
      return {
        show:true
      }
    },
    methods:{
      handleClick:function(){
        console.log('您點擊了')
      }
    }
  });
  var app = new Vue({
    el:'#app'
  });
</script>

    就此例來說,template寫法比Render函數寫法更加簡潔,所以要適當使用Render,否則只會增加編碼負擔。

 

 

 

 

 

 

.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM