目录
渲染函数使用场景
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()的使用
结语
由于时间有限,先写这么些,渲染函数有很多,我会在后续有时间的时候,把剩下的一一补充上,也欢迎大家对我这篇文章做出补充和修改