1. 程式人生 > 程式設計 >vue渲染方式render和template的區別

vue渲染方式render和template的區別

render函式詳解

Vue中的Render函式中有一個引數,這個引數是一個函式通常我們叫做h。其實這個h叫做createElement。Render函式將createElement的返回值放到了HTML中

createElement這個函式中有3個引數

第一個引數(必要引數):主要用於提供DOM的html內容,型別可以是字串、物件或函式

第二個引數(型別是物件,可選):用於設定這個DOM的一些樣式、屬性、傳的元件的引數、繫結事件之類

第三個引數(型別是陣列,陣列元素型別是VNode,可選):主要是指該結點下還有其他結點,用於設定分發的內容,包括新增的其他元件。注意,元件樹中的所有VNode必須是唯一的

// @return {VNode}
createElement(
 // {String | Object | Function}
 // 一個HTML標籤字串,元件選項物件,或者一個返回值型別為String/Object的函式。該引數是必須的
 'div',// {Object}
 // 一個包含模板相關屬性的資料物件,這樣我們可以在template中使用這些屬性,該引數是可選的。
{
   attrs: {
    name: headingId,href: '#'+headingId
  },style: {
    color: 'red',fontSize: '20px'
  },'class': {
    foo: true,bar: false
   },// DOM屬性
   domProps: {
     innerHTML: 'baz'
   },// 元件props
    props: {
     myProp: 'bar'
   },// 事件監聽基於 'on'
    // 所以不再支援如 'v-on:keyup.enter' 修飾語
    // 需要手動匹配 KeyCode 
    on: {
      click: function(event) {
        event.preventDefault();
        console.log(111);
     }
    }
 }

 // {String | Array}
 // 子節點(VNodes)由 createElement() 構建而成。可選引數
 // 或簡單的使用字串來生成的 "文字節點"。
[
  'xxxx',createElement('h1','一則頭條'),createElement(MyComponent,{
   props: {
    someProp: 'xxx'
  }
 }),this.$slots.default
]
)

什麼時候用render函式?

假設我們要封裝一套按鈕元件,按鈕有四個樣式(success、error、warning、default)。首先,你可能會想到如下實現

<template>
<divclass="btn btn-success"v-if="type === 'success'">{{ text }}</div>
<divclass="btn btn-danger"v-else-if="type === 'danger'">{{ text }}</div>
<divclass="btn btn-warning"v-else-if="type === 'warning'">{{ text }}</div>
</template>

雖然我們這樣實現沒有問題,但是如果現在有十幾個樣式的情況下我們就需要寫N多個判斷,如果遇到了這種情況我們就可以選擇使用render函式。

其實簡單的來說就是template適合簡單的元件封裝,然後render函式適合複雜的元件封裝

<script>
Vue.component("A-button",{
    props: {
      type: {
        type: String,default: 'default'
     },text: {
        type: String,default: '按鈕'
     }
   },computed: {
      tag() {
        switch(this.type) {
          case'success':
            return1;
          case'danger':
            return2;
          case'warning':
            return3;
          default:
            return1;
       }
     }
   },render(h) {
      returnh('div',{
        class: {
          btn: true,'btn-success': this.type==='success','btn-danger': this.type==='danger','btn-warning': this.type==='warning'
       },domProps: {
          //innerText: this.text,},on: {
          click: this.handleClick
       }
     },this.$slots.default
     );
   },methods: {
      handleClick() {
        console.log('-----------------------');
        console.log('li');
     }
   }
 })

  letvm=newVue({
    el: "#app"
 })
</script>

template與render函式對比

template----html的方式做渲染
render----js的方式做渲染

render(提供)是一種編譯方式
render裡有一個函式h,這個h的作用是將單檔案元件進行虛擬DOM的建立,然後再通過render進行解析。
h就是createElement()方法:createElement(標籤名稱,屬性配置,children)

template也是一種編譯方式,但是template最終還是要通過render的方式再次進行編譯。

區別:
1、render渲染方式可以讓我們將js發揮到極致,因為render的方式其實是通過createElement()進行虛擬DOM的建立。邏輯性比較強,適合複雜的元件封裝。
2、template是類似於html一樣的模板來進行元件的封裝。
3、render的效能比template的效能好很多
4、render函式優先順序大於template

案例一:template和render的方式渲染標題標籤:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <h-title level="1">標題</h-title>
    <h-title level="2">標題</h-title>
    <h-title level="3">標題</h-title>
  </div>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script>
    Vue.component("h-title",{
      /*  template渲染  */
      // template:`
      //   <div>
      //     <h1 v-if="level==1"><slot></slot></h1>  
      //     <h2 v-else-if="level==2"><slot></slot></h2>  
      //     <h3 v-else-if="level==3"><slot></slot></h3>  
      //   </div>
      // `,/*  render渲染  */
      render:function(h){
        // createElement(標籤名稱,children)
        return h("h"+this.level,{
            attrs:{
              "data-id":10
            }
          },// 相當於<slot></slot>標籤接收
          this.$slots.default
        )
      },props:{
        level:{
          type:String
        }
      }
    });
    let vm=new Vue({
      el:"#app"
    });
  </script>
</body>
</html>

案例二:render方式模擬button:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>Document</title>
  <style>
    *{margin: 0;padding: 0;}
    .btn{
      width: 80px;
      line-height: 40px;
      text-align: center;
      color:#fff;
      border-radius: 5px;
      background-color: #ccc;
    }
    .success{background-color: green;}
    .error{background-color: red;}
    .info{background-color: pink;}
  </style>
</head>
<body>
  <div id="app">
    <wql-button type="success">成功</wql-button>
    <wql-button type="info">提示</wql-button>
    <wql-button type="error">報錯</wql-button>
    <wql-button>預設</wql-button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    Vue.component("wql-button",{
      render:function(h){
        return h("div",{
          class:{
            btn:true,success:this.type=="success",error:this.type=="error",info:this.type=="info"
          }
        },this.$slots.default);
      },props:{
        type:{
          type:String
        }
      }
    });
    let vm=new Vue({
      el:"#app"
    });
  </script>
</body>
</html>

到此這篇關於vue渲染方式render和template的區別的文章就介紹到這了,更多相關vue render template區別內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!