new Vue({
  el: '#app'.render: h= > h(App)
})
Copy the code

In 2021, you won’t be unfamiliar with the above code, which will be present in main.js in any project built from scaffolding.

El is a mounted DOM element, which can be a DOM object or a selector.

Render is an arrow function, and h is a function that passes in a component object and hangs it on el

The createElement method function

This function is the argument to the Render function above, which returns a Virtual DOM object with up to three arguments

createElement (el, ? description, ? VNode) el Mandatory: {String | Object | Function} an HTML tag, component option, or a function (for functional components), for example:"div"Description Optional: {Object} a data object corresponding to the property, which applies to the el argument: {// Dynamically bind class, :class = {'active': true}
  'class': {
    active: true
  },
// dynamic binding style, :style = {'color': 'red'}
  'style': {
    color: 'red'
  },
// Attribute attribute of DOM element, id = 'SZGG ', name =' SZGG '
  'attrs': {
    id: 'szgg'.name: 'szgg'
  },
// The prop property received by the component, used when passing values to child components
  {
    props: {
      count: '0'}},// The property attribute of the DOM element
  domProps: {
    innerHTML: 'Elegance never goes out of style'
  },
@click=clickFn1 @click=clickFn1
  on: {
    click: this.clickFn1
  },
// Listen for the component's native event, which is only used on the component and is actually sent by $emit @click.native=clickFn2
  nativeOn: {
    click: thisClickFn2},// Self-defined directive, V-my-directives: SZGG. Bar ="1 + 1"
  directives: [{name: 'my-directives'./ / instructions
      value: 2.// The binding value of the directive
      expression: '1 + 1'.// The expression of the instruction
      arg: 'szgg'.// Command parameters
      modifiers: { // Modifiers for directives
        'bar': true}}]./ / scope slot, {name: props = > VNode | Array < VNode >}
/** 
       */
  scopedSlots: {
    default: props= > createElement('span', props.text)
  },
// If the component is a child of another component, specify a name for the slot
  slot: 'szgg'.// Other special top-level properties
  key: 'myKey'./ / ref attribute
  ref: 'myRef'.// if ref is used with v-for, add this attribute and $refs.myRef becomes an array
  refInFor: true} VNode Optional: {String | Array} child nodes, multiple child nodes are put into an array.'in the west' | [Ruthless Iron Hand.'Cripple strike']
Copy the code

Achieve a click function, click text color

After clicking = >

// Mount the Vue instance using the global component
<div id="app">
  <ele></ele>
</div>
...
.active {
  color: pink;
}
Copy the code
// the template attribute
<script>
  Vue.component('ele', {
    template: ` 
      
{{message}}
`
.data(){ return { isActive: true.message: 'SZGG'}},methods: { clickFn () { this.isActive = !this.isActive } } }); new Vue({ el:'#app'.data: {message:'HelloWorld' } }) </script> Copy the code
// render function overwrite
<script>
  Vue.component('ele', {
    data(){
      return {
        isActive: true}},render(createElement) {
      return createElement('div', {
        domProps: {
          id: 'szgg'
        },
        class: {
          'active': this.isActive
        },
        ref: 'szgg'.on: {
          click: this.clickFn
        }
      }, [createElement('p'.'SZGG')])},methods: {
      clickFn () {
        this.isActive = !this.isActive
      }
    }
  });
  new Vue({
    el:'#app'
  })
</script>
Copy the code

The above is just the first taste of the Render function, we can use it to implement the logic of the page, but also can use JS templates to implement V-if, V-for, V-model

v-if,v-for,v-model

We use logic to implement the above three instructions, rather than writing a custom implementation of the instructions, you can write your own

Implementation of V-if in render function

// The implementation of v-if is an if/else override
<script>
  Vue.component('ele', {
    data(){
      return {
        isActive: true}},render(createElement) {
      if (this.isActive) {
        return createElement('div', {
          domProps: {
            id: 'szgg'
          },
          class: {
            'active': this.isActive
          },
          ref: 'szgg'.on: {
            click: this.clickFn
          }
        }, [createElement('p'.'SZGG')])}else {
        return createElement('div', {
          on: {
            click: this.clickFn
          }
        }, 'Nothing')}},methods: {
      clickFn () {
        this.isActive = !this.isActive
      }
    }
  });
  new Vue({
    el:'#app'
  })
</script>
Copy the code

Implementation of V-for in the render function

// The implementation of v-for overwrites the map method of the array
<script>
  Vue.component('ele', {
    data(){
      return {
        list: [1.2.3.4.5]}},render(createElement) {
      if (this.list.length) {
        return createElement('ul'[this.list.map(i= > createElement('li', i))])
      } else {
        return createElement('p'."Why don't you have the data?")}}});new Vue({
    el: '#app'
  })
</script>
Copy the code

Implementation of V-model in render function

<script>
  Vue.component('ele', {
    data(){
      return {
        value: 'come'}},render(createElement) {
      // Save the current this object, the component object ele
      let _this = this;
      return createElement('input', {
        domProps: {
          value: _this.value
        },
        on: {
          input(event){
            _this.value = event.target.value
          }
        }
      })
    }
  });
  new Vue({
    el: '#app'
  })
</script>
Copy the code

Event modifier and key modifier

Table 1-1 Partial event and key modifiers and their corresponding handles

The modifier Corresponding to the handle
.stop event.stopPropagation()
.prevent event.preventDefault()
.self if (event.target ! == event.currentTarget) return
.enter/.13 if (event.keyCode ! == 13) return
.ctrl,.alt,.shift,.meta if (! event.ctrlKey) return

Special prefixes are provided for event modifiers. Capyure,.once, and Vue

Table 1-2 Event modifiers: capture, prefixes to.once

The modifier The prefix
.capture !
.once ~
.once.capture ~!

There are a lot of modifiers, so we’ll just implement a.enter function. Type the text in the input box and press Enter to type it on the public screen, as follows

<script>
  Vue.component('ele', {
    data(){
      return {
        value: ' '.list: []}},render(createElement) {
      // Save the current this object, the component object ele
      let _this = this;
      let listNode;
      if (this.list.length) {
      // Get the VNodes in the list
        listNode = createElement('ul'.this.list.map(i= > createElement('li', i)))
      } else {
        listNode = createElement('p'.'You put together something elegant.')}return createElement('div', [
        createElement('input', {
          attrs: {
            placeholder: 'Please enter an elegant statement'
          },
          domProps: {
            value: _this.value
          },
          on: {
            input(event){
              _this.value = event.target.value
            },
            // Listen for the keypress event, and then execute the logic if it is Enter
            keydown(event){
              if(event.key ! = ='Enter') return;
              _this.list.push(event.target.value);
              _this.value = ' '
            }
          }
        }),
        listNode
      ])
    }
  });
  new Vue({
    el: '#app'
  })
</script>
Copy the code

Slots in the Render function

The first step is to determine whether the component uses slots, that is, whether there is content between the component tags, which can be obtained with $slots.default

The default slot

<script>
  Vue.component('ele', {
    render(createElement) {
      console.log(this.$slots.default);
      if (this.$slots.default) {
        return createElement('div'.this.$slots.default)
      } else {
        return createElement('div'.'You didn't use the slot.')}}});new Vue({
    el: '#app'
  })
</script>
Copy the code

Scope slot

The implementation of a scoped slot has two points:

1. Bind data to slot tags, i.e.


{{props. Text}}

Code implementation

<div id="app">
  <ele>
    <template #default="scope">
      <span>{{scope.text}}</span>
    </template>
  </ele>
</div>
<script>
  Vue.component('ele', {
    data(){
      return {
        message: 'HelloWorld'}},render(createElement) {
    // Equivalent to '
        
', access the scope slots through this.$scopedSlots. Each scope slot is a function that returns several VNodes
return createElement('div'[this.$scopedSlots.default({ text: this.message }) ]) } }); new Vue({ el: '#app' })
</script>
Copy the code

The above code does the first step, we can test it to display the correct content on the page, but we still use the template to get the binding data, now we use the Render function to do the second step.

<div id="app">
</div>
<script>
  Vue.component('ele', {
    data(){
      return {
        message: 'HelloWorld'}},render(createElement) {
      return createElement('div'[this.$scopedSlots.default({
            text: this.message
          })
      ])
    }
  });
  new Vue({
    render(createElement) {
      return createElement('div'[/ / equivalent ` < div > < ele v - slot = "props" > < span > {{props. Text}} < / span > < / ele > < / div > `
          createElement('ele', {
            scopedSlots: {
              default: function (scope) {
                return createElement('span', scope.text)
              }
            }
          })
      ])
    }
  }).$mount('#app')
</script>
Copy the code

The above code is the completion code, using the Render function to implement the function of the scope slot

Functional component

With this information in mind, we can try to Render a component using the Render function, which defines the properties, behavior, and style of the component. What are the advantages of doing this?

The Render function returns a VNode, which is easier to Render. If we functionalize the components, we can improve the efficiency of rendering and reduce the cost of rendering

Vue. Js provides an attribute functional that, when set to true, can be stateless and instance-free, meaning that there is no data or this context. When the Render function provides the second parameter context to provide temporary context, could be obtained by the context components require data, props, slots, children, parent properties, such as: This. Message to context.props. Level and this.$slot. default to context.children

Here’s an example:

<div id="app"> <! --2.Passing data from the Vue instance to the component --><ele :l="l"></ele>
  <button @click="changeFn(1)">H1</button>
  <button @click="changeFn(2)">H2</button>
  <button @click="changeFn(3)">H3</button>
</div>
<script>
// Define a component pair
  let levelTitle = {
  // 5. The data is finally passed to the functional component
    props: ['level'].render(createElement) {
      return createElement(`hThe ${this.level}`.'I am' + this.level)
    }
  };
  Vue.component('ele', {
    // The functional component is enabled
    functional: true.render(createElement, context) {
      return createElement(levelTitle, {
      // 4. Pass props to this component, and pass ele to this component
        props: {
          level: context.props.l
        }
      })
    },
    // 3. The component accepts data
    props: {
      l: {
        type: Number}}});new Vue({
  // 1. Define initialization data
    data: {
      l: 1
    },
    methods: {
      changeFn(level){
        this.l = level
      }
    }
  }).$mount('#app')
</script>
Copy the code

We believe that the above examples should have a corresponding understanding of functional components, also let us under the charm of the Render function, but compared to the modular template, it is too much code to write, it is very inconvenient, so functional components are mainly used in the following two scenarios:

Programmatically select one of multiple components

Manipulate the children,props, and data before they are passed to the child components

This is the end of the Render function, which gives us another way to draw components and gives us a sense of the power of JS, and I’ve learned a lot from this exercise.

Reference:Vue website,Vue.js Practice (Books)