Vue-Deep1

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函数的第一个参数

第一个参数必须

creatElement(String / Object / Function)

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)

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  是作为构建函数的子节点

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  上下文对象

<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)
            }
          }
        }, '点击')
      }
    }
  }
})

猜你喜欢

转载自www.cnblogs.com/BUBU-Sourire/p/11439740.html