vue渲染函数render的使用例子(优化作用)
一、数据结构和渲染效果图
1.假设的数据结构如下:
2 页面效果如下
二、实现的方式
1、template去递归
首先编写子组件,loop-page.vue文件
// loop-page.vue
<template>
<!-- 注意此处的list-aaa 待会儿会说到 -->
<div class="list-aaa">
<div v-for="(item, index) in list" :key="index" class="list-item">
<div class="item-name">
<span>{{ item.name }}</span>
</div>
<template v-if="item.children">
<loop-page :list="item.children" class="children-item" />
</template>
</div>
</div>
</template>
<script>
export default {
name: "loopPage",
props: {
list: Array,
default: () => {
return []
}
}
}
</script>
<style scoped></style>
再新建index.vue父组件,编写代码如下
编译程序,得到的界面如下
不难可以看出,class="list-aaa"出现了三次。
递归组件在每层次递归都会把最外层的div添加进去,虽然看着多了一层没什么问题,但是随着一些有使用到slot插槽的组件时,在父子组件或同级组件会有数据间的关联。
由于多了一层div,原本渲染后的元素层级由父子或同级层级变成了爷孙层级,从而导致一些意想不到的隐藏BUG。
所以这里不能这么写,我找到一种办法就是用到了render函数。你们还有什么办法,也可以在评论区回复,一起学习哈~~~
2、render函数递归
1.改写子组件loop-page.vue文件,如下
//loop-page.vue
// 用render函数,需要去掉template标签
<script>
export default {
name: "loopPage",
props: {
list: Array,
default: () => {
return []
}
},
methods: {
loopH(h, list) {
return h(
'div',
{
attrs: {
class: 'list-item'
},
props: {
list: list
}
},
[
h('div', {
attrs: {
class: 'item-name'
}
}, [
h('span', list.name)
]),
(() => {
if (!list.children || !list.children.length) return []
return list.children.map((item) => {
return this.loopH(h, item)
})
})()
]
)
}
},
mounted() {
},
render(h) {
return this.loopH(h, this.list[0])
}
}
</script>
<style scoped>
</style>
这样生成的界面,就没有那个重复的嵌套关系了,一目了然,见下图
感觉还是看情况去使用,毕竟个人感觉template的方式还是比较通俗易懂,容易编写的。
喜欢这篇文章的可以点赞关注哈~