Make writing a habit together! This is the 10th day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

Render function — render

1, use,

HTML is usually created using templates, which is what VUE recommends, but you can also use JS to have complete control over HTML generation.

Render function:

An alternative to string templates that allow you to maximize the programming power of JavaScript. The render function takes a createElement method as the first argument to create a VNode.

The render function takes a function argument, uses the function to create a virtual DOM, and returns a virtual DOM.

Writing:

render: function (createElement) { 
    // The createElement function returns a VNode
    return createElement( 
        tag, // Label name
        data, // Pass data
        children // An array of vnodes)}Copy the code

Use the demo

<heading level="1" title="123">Ha, ha, ha</heading>
Copy the code
Vue.component('heading', {
    // To consider whether the user passes level, you can use object form to verify the data type or set it to mandatory
    props: {
        level: {
            type: String.required: true}},// Render receives this argument as h, since the underlying algorithm VNode uses is called snabbDOM, and the function that generates the virtual DOM is called H
    render(h) {
        let vnode = h( 
            'h' + this.level, // Label name
            {
                attrs: {
                    id: 'foo'}},// Pass data; Attributes that are not defined as prop are automatically added to the root element of the component
            this.$slots.default, // VNode array of children
        )
        console.log(vnode)
        return vnode
    }
})
Copy the code

CreateElement parameter

// @returns {VNode}
createElement(
  // {String | Object | Function}
  // An HTML tag name, component option object, or
  Resolve an async function of any of the above. Required fields.
  'div'.// {Object}
  // A data object corresponding to the attribute in the template. Optional.
  {
    // (See link to Further data Objects)
  },

  // {String | Array}
  // Child virtual nodes (VNodes), built from 'createElement()',
  // You can also use strings to generate "text virtual nodes". Optional.
  [
    'Write some words first.',
    createElement('h1'.'A headline'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'}})])Copy the code

Deep data object

/ / use
// 
      
       render title 1
      

// Enrich components
Vue.component('heading', {
    props: {
        level: {
            type: String.required: true
        },
        title: {
            type: String.default: ' '
        },
        icon: {
            type: String.default: ' '}},render(h) {
        // Array of child nodes
        let children = [];

        // icon attribute processing logic
        // <svg class="icon ">
        // 
      
        // </svg> 
        if(this.icon){
            children.push(h(
                'svg',
                {
                    class: 'icon',

                },
                [h(
                    'use',
                    {
                        attrs: {
                            'xlink:href': '#icon-'+ this.icon
                        }
                    }
                )]
            ))
        }
        // Add a child node: my-Component to pass parameters to
        children.push(h(
            'my-component',
            {
                props: {
                    message: 'Components.'}}))// Splice child nodes
        children = children.concat(this.$slots.default)

        let vnode = h( 
            'h' + this.level, // Label name
            {
                attrs: {
                    title: this.title
                },
                

            }, // Pass data; The data bound to the component can be moved to the root node without manual processing
            children, // VNode array of children
        )
        console.log(vnode)
        return vnode
    }
})


Vue.component('my-component', {
    props: ['message'].template: ` 
      
{{message}}
`
}) Copy the code

Functional component

1. Rendering functions

No state is managed, no state is listened to, and there are no lifecycle methods. Really, it’s just a function that accepts some prop. In such a scenario, we can mark the component as functional, which means it is stateless (no responsive data) and has no instance (no this context).

Will:

  • There is no state, that is, there is no data attribute defined inside the function
  • functional: trueMark components as functional components
  • Functional components have no instances, and you cannot access the context directly using this

Transform the above code into a functional component

// 
      
       render title 1
      


Vue.component('heading', {
    functional: true.// mark as a functional component
    // In versions prior to 2.3.0, the props option was required
    // In versions 2.3.0 and above, the props option can be omitted and attributes on all components are automatically resolved implicitly to prop.
    props: {
        level: {
            type: String.required: true
        },
        title: {
            type: String.default: ' '
        },
        icon: {
            type: String.default: ' '}},// Can't use template, use render; This, render passes context by context;
    render(h, context) {
        // Changes to attribute fetching
        const {icon, level, title} = context.props;

        // Array of child nodes
        let children = [];
        
        // icon attribute processing logic
        // <svg class="icon ">
        // 
      
        // </svg> 
        if(icon){
            children.push(h(
                'svg',
                {
                    class: 'icon',

                },
                [h(
                    'use',
                    {
                        attrs: {
                            'xlink:href': '#icon-'+ icon
                        }
                    }
                )]
            ))
        }
        // Concatenate the child node to update this.$slot. default to context.children
        children = children.concat(context.children)
        

        let vnode = h( 
            'h' + level, // Label name
            {
                attrs: {
                    title: title
                },
                

            }, // Pass data; The data bound to the component can be moved to the root node without manual processing
            children, // VNode array of children
        )
        
        return vnode
    }
})
Copy the code
  • summary
  1. If the component is a function component, the render function also receives an additional context parameter to provide context information for the function component that has no instance.

  2. Props option: In versions prior to 3.0, the props option is required. In versions 3.0 or later, you can omit the props option, and attributes on all components are automatically resolved implicitly to prop.

  3. Functional components are just functions and much less expensive to render

  4. Slots () differs from children. Children is all the children of slots; Slots () allows components to be aware of a slot mechanism, such as slots().default

2. Template-based functional components

Template-based functional components can be declared as follows:

<template functional>
</template>
Copy the code
<! -- Functional components -->
<template functional>
  <div :title='data.attrs.title'>
    {{data.attrs}}
    <slot name='header'/>
    <slot/>
  </div>
</template>
Copy the code
<! -- Using functional components -->
<functional-temp :title='title'>
  <template v-slot:header>The head</template>content</functional-temp>
Copy the code