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