[vue]Representación de funciones y componentes funcionales

¡Acostúmbrate a escribir juntos! Este es el décimo día de mi participación en el "Nuggets Daily New Plan · April Update Challenge", haz clic para ver los detalles del evento .

Función de renderizado -- renderizar

1. Uso

Por lo general, usamos plantillas para crear html, que también es la forma recomendada de vue, pero también podemos usar js para controlar completamente la generación de html.

función de renderizado:

Una alternativa a las plantillas de cadenas, que le permite usar JavaScript con todas sus capacidades de programación. La función de representación recibe un método createElement como primer parámetro para crear el VNode.

La función de representación recibe un parámetro de función, usa esta función para crear un DOM virtual y finalmente devuelve un DOM virtual.

Escritura:

render: function (createElement) { 
    // createElement函数返回结果是VNode 
    return createElement( 
        tag, // 标签名称 
        data, // 传递数据 
        children // 子节点(VNode)数组 
    ) 
}
复制代码

usar demostración

<heading level="1" title="123">哈哈哈</heading>
复制代码
Vue.component('heading', {
    // 考虑用户是否会传递level,可使用对象形式校验数据类型或设置为必填
    props: {
        level: {
            type: String,
            required: true
        }
    },
    // render接收的这个参数通常写为h,因为VNode在底层使用的算法叫snabbdom, 在这个算法里生成虚拟DOM的函数就叫做h
    render(h) {
        let vnode = h( 
            'h' + this.level, // 标签名称
            {
                attrs: {
                    id: 'foo'
                }
            }, // 传递数据;没有被定义为 prop 的 attribute ,它会自动添加到组件的根元素上
            this.$slots.default, // 子节点VNode数组
        )
        console.log(vnode)
        return vnode
    }
})
复制代码

3. parámetro createElement

// @returns {VNode}
createElement(
  // {String | Object | Function}
  // 一个 HTML 标签名、组件选项对象,或者
  // resolve 了上述任何一种的一个 async 函数。必填项。
  'div',

  // {Object}
  // 一个与模板中 attribute 对应的数据对象。可选。
  {
    // (详情见链接:深入数据对象)
  },

  // {String | Array}
  // 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
  // 也可以使用字符串来生成“文本虚拟节点”。可选。
  [
    '先写一些文字',
    createElement('h1', '一则头条'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'
      }
    })
  ]
)

复制代码

Profundice en los objetos de datos

// 使用 
// <heading level="1" title="fdsafsd" icon="zhongguoditu">render标题1</heading>

// 丰富组件
Vue.component('heading', {
    props: {
        level: {
            type: String,
            required: true
        },
        title: {
            type: String,
            default: ''
        },
        icon: {
            type: String,
            default: ''
        }
    },
    render(h) {
        // 子节点数组
        let children = [];

        // icon属性处理逻辑
        // <svg class="icon ">
        //     <use xlink:href="#icon-zhongguoditu"/>
        // </svg> 
        if(this.icon){
            children.push(h(
                'svg',
                {
                    class: 'icon',

                },
                [h(
                    'use',
                    {
                        attrs: {
                            'xlink:href': '#icon-'+ this.icon
                        }
                    }
                )]
            ))
        }
        // 再添加一个子节点:my-component组件,给其传递参数
        children.push(h(
            'my-component',
            {
                props: {
                    message: '组件啊'
                }
            }
        ))
        // 拼接子节点
        children = children.concat(this.$slots.default)

        let vnode = h( 
            'h' + this.level, // 标签名称
            {
                attrs: {
                    title: this.title
                },
                

            }, // 传递数据;给组件绑定的数据可以不用手动处理,它会自动移到这个根节点上
            children, // 子节点VNode数组
        )
        console.log(vnode)
        return vnode
    }
})


Vue.component('my-component', {
    props: ['message'],
    template: `
        <div>{{message}}</div>
    `
})
复制代码

componentes funcionales

1. Función de representación

No administra ningún estado, no escucha ningún estado que se le pase y no tiene métodos de ciclo de vida. En realidad, es solo una función que acepta algunos accesorios. En tal escenario, podemos marcar el componente como funcional, lo que significa que no tiene estado (sin datos reactivos) y no tiene instancia (sin este contexto).

Énfasis de la imagen:

  • No hay estado, es decir, el atributo de datos no está definido dentro de la función, etc.
  • functional: trueMarcar componentes como componentes funcionales
  • Los componentes funcionales no tienen instancia y no pueden acceder directamente al contexto usando este

Transforme el código anterior en un componente funcional

// <heading level="1" title="fdsafsd" icon="zhongguoditu">render标题1</heading>


Vue.component('heading', {
    functional: true, // 标记为函数式组件
    // 在 2.3.0 之前的版本中,props 选项是必须的
    // 在 2.3.0 或以上的版本中, 可以省略 props 选项,所有组件上的 attribute 都会被自动隐式解析为 prop。
    props: {
        level: {
            type: String,
            required: true
        },
        title: {
            type: String,
            default: ''
        },
        icon: {
            type: String,
            default: ''
        }
    },

    // 不能用template, 使用render; 没有实例,不存在this, render通过context传递上下文;
    render(h, context) {
        // 属性获取的变化
        const {icon, level, title} = context.props;

        // 子节点数组
        let children = [];
        
        // icon属性处理逻辑
        // <svg class="icon ">
        //     <use xlink:href="#icon-zhongguoditu"/>
        // </svg> 
        if(icon){
            children.push(h(
                'svg',
                {
                    class: 'icon',

                },
                [h(
                    'use',
                    {
                        attrs: {
                            'xlink:href': '#icon-'+ icon
                        }
                    }
                )]
            ))
        }
        // 拼接子节点  将this.$slots.default更新成context.children
        children = children.concat(context.children)
        

        let vnode = h( 
            'h' + level, // 标签名称
            {
                attrs: {
                    title: title
                },
                

            }, // 传递数据;给组件绑定的数据可以不用手动处理,它会自动移到这个根节点上
            children, // 子节点VNode数组
        )
        
        return vnode
    }
})
复制代码
  • resumen
  1. Si el componente es un componente de función, la función de representación también recibe un parámetro de contexto adicional para proporcionar información de contexto para los componentes de función que no tienen una instancia.

  2. Opción props:
    en versiones anteriores a la 2.3.0, se requiere la opción props
    En la versión 2.3.0 o superior, la opción props se puede omitir y los atributos de todos los componentes se resolverán automática e implícitamente en props.

  3. Los componentes funcionales son solo funciones, con una sobrecarga de representación mucho menor

  4. slots()La childrendiferencia con:
    los niños se refieren a todos los nodos secundarios;
    mientras que slots()los componentes pueden ser conscientes de un mecanismo de ranura, como slots().defaultel contenido anónimo predeterminado

2. Componentes funcionales basados ​​en plantillas

Los componentes funcionales basados ​​en plantillas se pueden declarar así:

<template functional>
</template>
复制代码
<!--函数式组件-->
<template functional>
  <div :title='data.attrs.title'>
    {{data.attrs}}
    <slot name='header'/>
    <slot/>
  </div>
</template>
复制代码
<!--使用函数式组件-->
<functional-temp :title='title'>
  <template v-slot:header>
      头部
  </template>
  内容
</functional-temp>
复制代码

Supongo que te gusta

Origin juejin.im/post/7086758554136215565
Recomendado
Clasificación