vue3 渲染函数

能解决的问题

有时候使用模板编写某些组件的时候会特别麻烦,使用渲染函数反而可以很简单的解决

什么是渲染函数

就是使用vue内置的一些API写一些JS代码,就这么简单

渲染函数编写方式及封装成组件(个人还是觉得封装成组件好用)
import { defineComponent, h } from 'vue';
export default defineComponent({
    name: 'Demo',
    props: {
        name: {
            type: String,
            default: '1'
        }
    },
    render() {
        return h(
            'h1',
            {
                class: 'demoClass',
                name: 'ceshi',
                style: { color: 'red' },
                onclick: () => console.log(this)
            },
            [
                this.name,
                this.$slots.default(),
            ]


        )
    }
})

从上面代码可以看出,我们可以在一个新建的JS或TS文件中引入defineComponent函数,引入这个函数大家后大家就应该很熟悉了

  1. 首先定义一下这个组件的名字
  2. 定义组件接收的数据 props
  3. 使用render函数定义组件的模板
    1 render是一个函数 ,一个函数肯定是能返回点什么,如果我们只是返回一个字符串,像下面这种

			render() {
        	return '123'
        }

那么页面就只是简单的显示返回的字符串,不包含任何的HTML
这个时候h 函数就上场了,h有三个参数:
第一个参数:HTML标签名
参数类型可以是字符串,object,function
第二个参数:HTML 属性 方法等
参数类型 JSON格式的对象,里面可以像在HTML上写属性方法一样
第三个参数 子元素/渲染内容/插槽
一个参数的话,不需要使用数组包裹,多个参数的话,放在数组里面 ,用逗号分割
2 h函数中的this是啥

name: (…)
$: (…)
$attrs: (…)
$data: (…)
$el: (…)
$emit: (…)
$forceUpdate: (…)
$nextTick: (…)
$options: (…)
$parent: (…)
$props: (…)
$refs: (…)
$root: (…)
$slots: (…)
$watch: (…)
_: (…)

可以看出this就是组件实例对象,里面有各种方法,都可以使用this.来调用

约束 vnode唯一

个人理解的官方实例是 使用h函数创建模板,会像我们在JS中创建对象一样,有一个内存地址,如果我们在h函数中渲染了相同地址的子元素,vue 就会报错

render() {
  const myParagraphVNode = h('p', 'hi')
  return h('div', [
    // 错误 - 重复的 Vnode!
    myParagraphVNode, myParagraphVNode
  ])
}

使用if else 和 v-for

在渲染函数中使用判断条件和循环条件,就像我们在JS中使用一样,只是这个函数是返回函数,要把h 函数返回

render() {
        // return '999999'   'h1',
        return h(
            () => {
                if (len.length) {
                    return h('ul', len.map((item) => {
                        return h(`h${item}`,
                        {
                            style:{fontSize:'30px'}
                        }, 
                        `wode${item}`)
                    }))
                }
            },
            // 'h1',
            {
                class: 'demoClass',
                name: 'ceshi',
                style: { color: 'red' },
                onClick: () => console.log(this)
            },
            [
                this.name,
                this.$slots.default(),
            ]


        )
    }

在最外面的写的标签属性作用于最外层,如果在第一个参数的返回函数中写上,那就是子节点的,和平时写DOM一样

v-model

和组件模板上的一样 modelValue 和 update:modelValue : 函数返回 e.target.value
官网实例

props: ['modelValue'],
emits: ['update:modelValue'],
render() {
  return h(SomeComponent, {
    modelValue: this.modelValue,
    'onUpdate:modelValue': value => this.$emit('update:modelValue', value)
  })
}

事件

以on开头 ,事件名首字母大写

render() {
  return h('input', {
    onClickCapture: this.doThisInCapturingMode,
    onKeyupOnce: this.doThisOnce,
    onMouseoverOnceCapture: this.doThisOnceInCapturingMode
  })
}

作用域插槽

渲染函数的作用域插槽基本上和模板组件上差不多,只不过写法不一样,this.$slots.插槽名({

})
插槽是个函数,如果是作用域插槽的话里面就是放个JSON字符串,普通插槽的话就不用放JSON字符串

				this.$slots.ceshi({
                    ceshiName:'123'
                }),

有什么问题可以留言讨论

仅记录平常学习

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值