国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

了解VUE的render函數的使用

2019-11-19 16:23:58
字體:
來源:轉載
供稿:網友

Vue 推薦在絕大多數情況下使用 template 來創建你的 HTML。然而在一些場景中,你真的需要 JavaScript 的完全編程的能力,這就是 render 函數,它比 template 更接近編譯器。 在 HTML 層, 我們決定這樣定義組件接口:通過傳入不同的level 1-6 生成h1-h6標簽,和使用slot生成內容

<div id="div1">  <child :level="1">Hello world!</child></div><script type="text/x-template" id="child-template"> <h1 v-if="level === 1">  <slot></slot> </h1> <h2 v-if="level === 2">  <slot></slot> </h2> <h3 v-if="level === 3">  <slot></slot> </h3> <h4 v-if="level === 4">  <slot></slot> </h4> <h5 v-if="level === 5">  <slot></slot> </h5> <h6 v-if="level === 6">  <slot></slot> </h6> </script><script type="text/javascript">  /**   * 全局注冊child組件,注意template如果值以 # 開始,則它用作選項符,將使用匹配元素的 innerHTML 作為模板。常用的技巧是用 <script type="x-template"> 包含模板,這樣的好處是html不會渲染里面的內容   * 這里使用template不是最好的選擇,   * 一、代碼冗長    * 二、在不同的標題插入內容需要重復使用slot    * 三、由于組件必須有根元素,所以標題和內容被包裹在一個無用的div中,比如<div><h1>hello world</h1></div>   */  Vue.component('child', {   template: '#child-template',   props: {    level: {     type: Number,     required: true    }   },   data: function() {    return {     a: 1    }   }  })  new Vue({    el:"#div1"  }) </script>

我們嘗試使用render函數實現上面的例子,注意使用render函數,template 選項將被忽略。 createElement接收3個參數:

第一個參數可以是HTML標簽名,組件或者函數都可以;此參數是必須的;

第二個為數據對象{Object}(可選);

第三個為子節點{String | Array}(可選),多個子節點[createElement(tag1),createElement(tag2)]。

<div id="div1">  <child :level="1">   Hello world!  </child>  <child :level="2">   <!-- 將不會被顯示 -->   <span slot="footer">span</span>   <p slot="header">header slot<span>span</span></p>  </child> </div>Vue.component('child', {   render: function(createElement) {    console.log(this.$slots);    return createElement(     'h'+ this.level, // tagName標簽名稱     {      // 為每個h標簽設置class      'class': {       foo: true,       bar: false      },      // 最終被渲染為內聯樣式      style: {       color: 'red',       fontSize: '14px'      },      // 其他的html屬性      attrs: {       id: 'foo',       'data-id': 'bar'      },      // DOM屬性      domProps: {       // innerHTML: 'from domProps',      },      // 事件監聽器基于 "on"      // 所以不再支持如 v-on:keyup.enter 修飾器      on: {       click: this.clickHandler      },      // ...     },     // 你可以從this.$slots獲取VNodes列表中的靜態內容     // $slots.default用來訪問組件的不具名slot     // 當你可能需要具名slot的時候需要指定slot的name, this.$slots.header     [this.$slots.default]    )   },   template: '<div v-if="level===1"><slot></slot></div>', // 將被忽略   props: {    level: {     type: Number,     required: true    }   },   methods: {    clickHandler: function() {     console.log('clickHandler')    }   }  })  new Vue({    el:"#div1"  })

我們現在可以完成這樣的組件

<h1>   <a name="hello-world" href="#hello-world" rel="external nofollow" >    Hello world!   </a></h1>// 遞歸函數獲得helloworld文本  function getChildrenTextContent(child) {    return child.map(function(node) {      return node.children? getChildrenTextContent(node.children) : node.text    }).join('')  }  Vue.component('child',{    render: function(createElement) {      var hello_world = getChildrenTextContent(this.$slots.default)               .toLowerCase()               .replace(//W+/g,'-')               .replace(/^/-|/-$/g,'');      return createElement(        'h'+ this.level,        {},        [ // 創建一個a標簽,設置屬性,并設置a標簽的子節點          createElement('a',{            attrs: {              name: hello_world,              href: '#' + hello_world            }          },this.$slots.default)        ]      )    },    props: {      level: {        type: Number,        required: true      }    }  })  new Vue({    el:"#div1"  })

注意VNode的唯一性,這里兩個VNode指向同一引用是錯誤的,如果要重復創建多個相同元素/組件,可以使用工廠函數實現

<div id="div1">  <child :level="1">   Hello world!  </child></div>Vue.component('child',{  // render: function(createElement) {  // var myParagraphVNode = createElement('p','hello')  // return createElement('div',  //   [myParagraphVNode, myParagraphVNode]  // )  // },  render: function(createElement) {    return createElement('div',      Array.apply(null, {length:20}).map(function() {        return createElement('p','hello')      })    )  },  props: {    level: {      type: Number,      required: true    }  }})new Vue({  el:"#div1"})

使用javascript代替模板功能,某些api要自己實現

①使用if/else代替v-if

②使用map代替v-for

Vue.component('child',{  render: function(createElement) {    if (this.lists.length) {      return createElement('ul',this.lists.map(function() {        return createElement('li','hi')      }))    } else {      return createElement('p','no lists')    }  },  props: {    level: {      type: Number,      required: true    }  },  data: function() {    return {      lists: [1,2,3]    }  }})// render函數中沒有與v-model相應的api - 你必須自己來實現相應的邏輯:Vue.component('child-msg',{  render: function(createElement) {    var self = this;    return createElement('div', [        createElement('input',{          'on': {            input: function(event) {              self.value = event.target.value;            }          }        }),createElement('p',self.value)      ])  },  props: {    level: {      type: Number,      required: true    }  },  data: function() {    return {      value: ''    }  }})new Vue({  el:"#div1"})

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 甘肃省| 来安县| 济南市| 丹棱县| 项城市| 离岛区| 彰化市| 叶城县| 新化县| 锡林浩特市| 唐山市| 南丹县| 成安县| 永定县| 罗田县| 思茅市| 云林县| 贵定县| 三都| 周至县| 富阳市| 阿拉善左旗| 布尔津县| 武宁县| 旅游| 额尔古纳市| 禹州市| 广德县| 农安县| 兴文县| 雷山县| 区。| 潜江市| 崇左市| 天峨县| 顺昌县| 博乐市| 顺昌县| 雅安市| 江永县| 塔河县|