vue3进阶,渲染函数使用

目录

渲染函数使用场景

h() 渲染函数

渲染函数基础写法

渲染函数的组件传参,事件传递

渲染函数的插槽使用

结语


渲染函数使用场景

        在写这篇文章之前,我会先简单说一下渲染函数,并且我会在第一个渲染函数的介绍中,标名渲染函数的各种写法,在后续的渲染函数介绍中,我就只采用单一的写法去实现了。        

         这里附上官方网址https://cn.vuejs.org/api/render-function.html       

        话不多说,正片开始!

        Vue 3项目中,渲染函数 (`render` function) 通常不是默认的选择,因为Vue的模板语法已经足够强大和灵活,可以满足大多数开发需求。然而,在某些特定的场景下,渲染函数会非常有用,因为render渲染的优先级是高于template的尤其是在需要高度动态内容或者优化性能的情况下。以下是一些可能使用渲染函数的项目实战场景:


        1. **复杂的动态内容**:当你的组件需要根据不同的条件渲染高度动态的结构时,渲染函数可以提供更大的灵活性。例如,根据数据动态生成表格、列表或者树形结构。
        2. **自定义渲染逻辑**:在某些情况下,你可能需要自定义渲染逻辑,比如实现一个复杂的自定义组件(如日期选择器、富文本编辑器等)。
        3. **性能优化**:在使用虚拟DOM的场景中,通过渲染函数可以更精细地控制DOM的更新,减少不必要的渲染,从而提高性能。
        4. ** JSX/TSX**:如果你使用的是TypeScript或者喜欢React的JSX语法,你可以结合Vue的渲染函数和JSX插件来实现类似React的开发体验。
        5. **函数式组件**:在Vue中,函数式组件通常与渲染函数一起使用,因为它们没有状态(state)和管理生命周期钩子的需要,可以提供更高的性能。
        6. **图形和可视化**:在开发图形界面(如图表、地图等)时,渲染函数可以提供更直接的方式来操作图形元素。
        7. **递归组件**:当需要渲染递归组件(比如树形控件)时,渲染函数可以更方便地处理递归逻辑。
        8. **外部库集成**:当需要将Vue与其他JavaScript库集成时,可能会用到渲染函数来桥接两者之间的DOM操作。


        在实际项目中,渲染函数的使用通常需要开发者对Vue的内部机制有较深的理解。因此,在决定是否使用渲染函数时,应该权衡其带来的灵活性和维护成本。对于大多数常规的UI开发任务,Vue的模板语法已经足够使用,而且更容易理解和维护。只有在遇到上述提到的特定场景时,才考虑使用渲染函数。

h() 渲染函数

先写一下几种写法,这几种写法参考了这篇文章:https://juejin.cn/post/7243357900939919418?searchId=20240703154620A17D2DF9F258021408F2

选项式API:

import { h } from 'vue'

export default {
  data() {
    return {
      msg: 'hello'
    }
  },
  render() {
    return h('div', this.msg)
  }
}

 组合式API:

// 无须template部分,就会在页面显示一个div。
import { ref, h } from 'vue'

export default {
  props: {
    /* ... */
  },
  setup(props) {
    const count = ref(1)

    // 返回渲染函数
    return () => h('div', props.msg + count.value)
  }
}

组合式API+setup语法糖:

<template>
  <hd />
</template>
<script lang="tsx" setup>
import { h } from 'vue'

// 返回一个组件hd
const hd = h(
  'div',
  Array.from({ length: 20 }).map(() => {
    return h('p', 'hi')
  })
)
</script>

在接下来所有的例子中,我都会使用组合式API+setup语法糖

渲染函数基础写法

首先介绍一下基础写法:

<template>
  <div>
    <hd />
  </div>
</template>

<script setup>
    import { h } from 'vue'
    const hd = h('div', { 
                            class: 'className', 
                            id: 'idName', 
                            innerHTML: 'hello', 
                            style: {                 
                                    background: 'yellow',
                                    padding: '10px', 
                                    width: '70px' 
                                   } 
                        }
                 )
</script>

这段代码在页面上就是这样展示的:

不知道大家发现没有,这种写法就跟react中JSX很像了,都是吧DOM作为对象

渲染函数的组件传参,事件传递

当然,这种语法常见的写法还是要引入组件

子组件ceshi.vue中:

<template>
  <div>
    这是测试引入的组件
    {{ props.someProp }}
    <button @click="ceshiChrild">按钮</button>
  </div>
</template>

<script setup>
import { ref, defineEmits, defineProps } from 'vue'

const props = defineProps({
  someProp: {
    type: String,
    default: ''
  }
})

const emit = defineEmits(['ceshiApi'])

const ceshiChrild = () => {
  emit('ceshiApi')
}

</script>

父组件中:

<template>
  <div>
    <hd />
    <ceshiZuJian />
  </div>
</template>

<script setup>
import { ref, h } from 'vue'


import ceshi from './ceshi.vue'

const hd = h('div', { class: 'className', id: 'idName', innerHTML: 'hello', style: { background: 'yellow', padding: '10px', width: '70px' } })

const ceshiZuJian = h(ceshi, {
  // 等价于 some-prop="hello"
  someProp: '传入的数据',
  // 等价于 @ceshiApi="ceshiApiInner()"
  onCeshiApi: () => { ceshiApiInner() }
})

const ceshiApiInner = () => {
  console.log('ceshi');
}

</script>

这样展示出来的样子就是这样的:

点击按钮,会打印‘ceshi’

至此,组件的引入,传参,事件触发展示完毕

渲染函数的插槽使用

这点学完之后,就基本上可以用渲染函数h()做很多工作了

官网中给出的例子是这样的:

官网给出的这种写法展示了在Vue 3中使用渲染函数 (h) 时,如何传递插槽内容给子组件。在Vue 3中,h函数可以接受三个参数:第一个参数是组件或者HTML标签名,第二个参数是传递给组件的属性和事件监听器,第三个参数是插槽内容。

我个人不太喜欢这种写法,而且在我们日常的开发中,我认为只需要掌握最常见的具名插槽,就可以满足绝大部分应用场景,所以我在这里就只去写具名插槽的使用了

子组件:

<template>
  <div>
    这是测试引入的组件
    {{ props.someProp }}
    <button @click="ceshiChrild">按钮</button>
    <slot name="footer"></slot>
  </div>
</template>

<script setup>
import { ref, defineEmits, defineProps } from 'vue'

const props = defineProps({
  someProp: {
    type: String,
    default: ''
  }
})

const emit = defineEmits(['ceshiApi'])

const ceshiChrild = () => {
  emit('ceshiApi')
}

</script>

父组件:

<template>
  <div>
    <hd />
    <ceshiZuJian />
  </div>
</template>

<script setup>
import { ref, h } from 'vue'

import ceshi from './ceshi.vue'

const hd = h('div', { class: 'className', id: 'idName', innerHTML: 'hello', style: { background: 'yellow', padding: '10px', width: '70px' } })

const ceshiZuJian = h(ceshi, {
  // 等价于 some-prop="hello"
  someProp: '传入的数据',
  // 等价于 @ceshiApi="ceshiApiInner()"
  onCeshiApi: () => { ceshiApiInner() }
}, {
  // 使用 slots 对象定义具名插槽
  footer: () => h('h1', '这是底部内容')
})

const ceshiApiInner = () => {
  console.log('ceshi');
}

onMounted(() => {

})
</script>

上面展示出来的样子就是这样:

至此,我们就学完了绝大部分关于渲染函数h()的使用

结语

由于时间有限,先写这么些,渲染函数有很多,我会在后续有时间的时候,把剩下的一一补充上,也欢迎大家对我这篇文章做出补充和修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值