Vue-render函數

render函數

 

vue組件定義方法

  • 原始方法
<div id="app">
  <sth :level=level>標題在此</sth>
  <template id='plug'>
    <div>
      <h1 v-if="level===1">
        <slot></slot>
      </h1>
      <h2 v-if="level===2">
        <slot></slot>
      </h2>
      <h3 v-if="level===3">
        <slot></slot>
      </h3>
    </div>
  </template>
</div>
var app = new Vue({
  el: '#app',
  data:{
  level:1
  },
  components: {
    'sth': {
      props: ['level'],
      template: '#plug'
    }
  }
})

 

  • 使用render函數
<div id="app">
  <sth :level=level>標題在此</sth>
</div>
var app = new Vue({
  el: '#app',
  data: {
    level: 3
  },
  components: {
    'sth': {
      props: ['level'],
      render(createElement) {
        return creatEelement('h' + this.level, this.$slots.default) //this.$slots.default 子節點數組
      }
    }
  }
})

 

render函數的第一個參數

第一個參數必須html

creatElement(String / Object / Function)vue

var app = new Vue({
  el: '#app',
  components: {
    'sth': {
      render(createElement) {
        /* return createElement('div')   ---String*/
        /* return createElement({
          template: '<span></span>'     ---Object
        }) */
        var fun = function() {
          return {
            template: '<h1></h1>'
          }
        }
        return createElement(fun())        //---Function
      }
    }
  }
})

 

render函數的第二個參數

第二個參數可選,是數據對象,必須是Object數組

creatElement(第一個參數,第二個參數:Object)app

var app = new Vue({
  el: '#app',
  components: {
    'sth': {
      render(createElement) {
        return createElement({
          //第一個參數
          template: '<div>內容</div>'
        }, { //第二個參數——數據對象  只能是Object
          //類名:布爾
          'class': {
            too: true,
            foo: false
          },
          style: {
            color: 'red',
            fontSize: '18px'
          },
          //正常html特性
          attrs: {
            id: 'aaa',
            src: 'bbb'
          },
          //原生的dom屬性
          domProps:{
          innerHTML:'<span style="color:blue;font-size="20px">鬧心</span>'
          }
        })
      }
    }
  }
})

 

render函數的第三個參數

第三個參數可選,Object / Array  是做爲構建函數的子節點dom

var app = new Vue({
  el: '#app',
  components: {
    'sth': {
      render(createElement) {
        return createElement('div', [
          createElement('h1', '標題1'), //div的子節點
          createElement('h4', '標題4') //div的子節點
        ])
      }
    }
  }
})

 

在render函數中使用插槽

<div id="app">
  <sth>
    <p>內容</p>
    <p>內容</p>
    <p>內容</p>
    <h1 slot='header'>標題</h1>
    <h3 slot='footer'>底部</h3>
  </sth>
</div>
let app = new Vue({
  el: '#app',
  components: {
    'sth': {
      render(createElement) {
        var header = this.$slots.header
        var main = this.$slots.default
        var footer = this.$slots.footer
        return createElement('div', [
          createElement('header', header), //這邊的header是虛擬節點--數組
          createElement('main', main),
          createElement('footer', footer)
        ])
      }
    }
  }
})

 

在render函數中使用props

<div id="app">
  <sth :show='show'></sth>
  <button @click='change_img'>點擊切換</button> {{show}}
</div>
let app = new Vue({
  el: '#app',
  data: {
    show: false
  },
  methods: {
    change_img() {
      this.show = !this.show
    }
  },
  components: {
    'sth': {
      props: ['show'],
      render(createElement) {
        var img
        if (this.show) {
          img = 'https://w.wallhaven.cc/full/0w/wallhaven-0wpxxr.jpg'
        } else {
          img = 'https://w.wallhaven.cc/full/4g/wallhaven-4gyqm3.jpg'
        }
        return createElement('img', {
          attrs: {
            src: img
          },
          style: {
            width: '300px',
            height: '150px'
          }
        })
      }
    }
  }
})

 

在render函數中使用v-model

<div id="app">
  <sth :name='name' v-model='name'></sth> {{name}}
</div>
new Vue({
  el: '#app',
  data: {
    name: ''
  },
  components: {
    'sth': {
      render(createElement) {
        var self = this
        return createElement('input', {
          domProps: {
            value: self.name
          },
          on: {
            input(ev) {
              self.$emit('input', ev.target.value)
            }
            //這裏的this默認是指向window,須要改變this指向爲Vue實例
            //input:function(ev){this.$emit('input',ev.target.value)}
          }
        })
      },
      props: ['name']
    }
  }
})

 

在render函數中使用做用域插槽

<div id="app">
  <sth>
    <template scope='prop'>
      {{prop.text}}
      {{prop.msg}}
    </template>
  </sth>
</div>
let app = new Vue({
  el: '#app',
  components: {
    'sth': {
      render(createElement) {
        return createElement('div', this.$scopedSlots.default({
          text: '哈哈哈',
          msg: 'aaaa'
        }))
      }
    }
  }
})

 

函數化組件

沒有data和this的概念函數

萬能context  上下文對象this

<div id="app">
  <sth value='aaa'></sth>
</div>
let app = new Vue({
  el: '#app',
  components: {
    'sth': {
      props: ['value'],
      functional: true, //表示當前的vue實例無狀態,無實例
      render(createElement, context) {
        return createElement('button', {
          on: {
            click() {
              console.log(context)
              console.log(context.parent)
              console.log(context.props.value)
            }
          }
        }, '點擊')
      }
    }
  }
})
相關文章
相關標籤/搜索