Vue 综合- render

120 阅读1分钟

render() 基础

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

// 子组件
const compoent = {
  // template: `
  // <div :style="style">
  //   <slot></slot>
  // </div>
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style
    }, this.$slots.default)
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      }
    }
  }
}

// 父组件
new Vue({
  el: '#app',
  components: {
    compOne: compoent
  },
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp, this.$refs.span);
  },

  // template: `
  // <comp-one ref="comp">
  //   <span ref="span">{{value}}</span>
  // </comp-one>
  // `,

  // 这里就以上面的 template 里面的组件进行分析在 render() 方法里面是如何运行出来的。
  // 每个Vue的实例都会调用 createElement()
  // render () { 
  //   return this.$createElement()
  // }

  // 每个Vue的实例都会传过来一个 createElement,可以只需要声明直接调用就行了,这两个结果是一样的,不需要太在意用哪个
  // render (createElement) { 
  //   return createElement()
  // }

  // 这里我用第二种方法来使用
  render (createElement) { 
    return createElement('comp-one', {
      ref: 'comp'
    }, [
      createElement('span',{
        ref: 'comp'
      }, this.value)
    ])
  }
})

但是上面只是单独的插槽方式使用,如果还需要多带几个参数进去,则需要这么使用:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

// 子组件
const compoent = {
  props: ['prop1'],
  // template: `
  // <div :style="style">
  //   <slot></slot>
  // </div>
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style
    }, [
      this.$slots.default, // 如果 slot 是有名字的,则 .default 可换成 slot 的名字。
      this.prop1
    ])
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      }
    }
  }
}

// 父组件
new Vue({
  el: '#app',
  components: {
    compOne: compoent
  },
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp, this.$refs.span);
  },
  // template: `
  // <comp-one ref="comp">
  //   <span ref="span">{{value}}</span>
  // </comp-one>
  // `,
  render (createElement) { 
    return createElement('comp-one', {
      ref: 'comp',
      props: {
        prop1: 'dzm' // 输出 123dzm
        // prop1: this.value // 输出 123123
      }
    }, [
      createElement('span',{
        ref: 'comp'
      }, this.value)
    ])
  }
})

render() on 事件绑定

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

// 子组件
const compoent = {
  props: ['prop1'],
  // template: `
  // <div :style="style">
  //   <slot></slot>
  // </div>
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style,
      on: {
        click: () => { this.$emit('click') }
      }
    }, [
      this.$slots.default,
      this.prop1
    ])
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      }
    }
  }
}

// 父组件
new Vue({
  el: '#app',
  components: {
    compOne: compoent
  },
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp, this.$refs.span);
  },
  methods: {
    handleClick () {
      alert(1)
    }
  },
  // template: `
  // <comp-one ref="comp">
  //   <span ref="span">{{value}}</span>
  // </comp-one>
  // `,
  // 这里我用第二种方法来使用
  render (createElement) { 
    return createElement('comp-one', {
      ref: 'comp',
      props: { // 参数
        prop1: 'dzm' // 输出 123dzm
        // prop1: this.value // 输出 123123
      },
      on: { // 点击事件
        click: this.handleClick
      }
    }, [
      createElement('span',{
        ref: 'comp'
      }, this.value)
    ])
  }
})

on: 事件不会自动绑定到当前节点上面,需要手动的再去触发。 nativeOn: 事件会自动的去绑定到当前的节点上面,不需要在子节点里面重写触发。


render() nativeOn 事件绑定

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

// 子组件
const compoent = {
  props: ['prop1'],
  // template: `
  // <div :style="style">
  //   <slot></slot>
  // </div>
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style
      // on: {
      //   click: () => { this.$emit('click') }
      // }
    }, [
      this.$slots.default,
      this.prop1
    ])
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      }
    }
  }
}

// 父组件
new Vue({
  el: '#app',
  components: {
    compOne: compoent
  },
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp, this.$refs.span);
  },
  methods: {
    handleClick () {
      alert(1)
    }
  },
  // template: `
  // <comp-one ref="comp">
  //   <span ref="span">{{value}}</span>
  // </comp-one>
  // `,
  // 这里我用第二种方法来使用
  render (createElement) { 
    return createElement('comp-one', {
      ref: 'comp',
      props: { // 参数
        prop1: 'dzm' // 输出 123dzm
        // prop1: this.value // 输出 123123
      },
      // on: { // 点击事件
      //   click: this.handleClick
      // },
      nativeOn: {
        click: this.handleClick
      }
    }, [
      createElement('span',{
        ref: 'comp'
      }, this.value)
    ])
  }
})

render() 里面 slot name的使用

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

// 子组件
const compoent = {
  props: ['prop1'],
  // template: `
  // <div :style="style">
  //   <slot></slot>
  // </div>
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style
      // on: {
      //   click: () => { this.$emit('click') }
      // }
    }, [
      this.$slots.header, // 如果 slot 是有名字的,则 .default 可换成slot的名字。
      this.prop1
    ])
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      }
    }
  }
}

// 父组件
new Vue({
  el: '#app',
  components: {
    compOne: compoent
  },
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp, this.$refs.span);
  },
  methods: {
    handleClick () {
      alert(1)
    }
  },
  // template: `
  // <comp-one ref="comp">
  //   <span ref="span">{{value}}</span>
  // </comp-one>
  // `,
  // 这里我用第二种方法来使用
  render (createElement) { 
    return createElement('comp-one', {
      ref: 'comp',
      props: { // 参数
        prop1: 'dzm' // 输出 123dzm
        // prop1: this.value // 输出 123123
      },
      // on: { // 点击事件
      //   click: this.handleClick
      // },
      nativeOn: {
        click: this.handleClick
      }
    }, [
      createElement('span',{
        ref: 'comp',
        slot: 'header'
      }, this.value)
    ])
  }
})

render() 里面 domProps attrs 的使用

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

// 子组件
const compoent = {
  props: ['prop1'],
  // template: `
  // <div :style="style">
  //   <slot></slot>
  // </div>
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style
      // on: {
      //   click: () => { this.$emit('click') }
      // }
    }, [
      this.$slots.header, // 如果 slot 是有名字的,则 .default 可换成slot的名字。
      this.prop1
    ])
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      }
    }
  }
}

// 父组件
new Vue({
  el: '#app',
  components: {
    compOne: compoent
  },
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp, this.$refs.span);
  },
  methods: {
    handleClick () {
      alert(1)
    }
  },
  // template: `
  // <comp-one ref="comp">
  //   <span ref="span">{{value}}</span>
  // </comp-one>
  // `,
  // 这里我用第二种方法来使用
  render (createElement) { 
    return createElement('comp-one', {
      ref: 'comp',
      props: { // 参数
        prop1: 'dzm' // 输出 123dzm
        // prop1: this.value // 输出 123123
      },
      // on: { // 点击事件
      //   click: this.handleClick
      // },
      nativeOn: {
        click: this.handleClick
      }
    }, [
      createElement('span',{
        ref: 'comp',
        slot: 'header',
        attrs: {
          id: 'test-id'
        }
        // domProps:{ // 传入这个之后, 传入的 this.value 就没有效果了,会被 domProps 的里面替换掉
        //   innerHTML: '<span>345</span>'
        // }
      }, this.value)
    ])
  }
})