vue 递归组件 (评论列表)
一、引入
最近某项目中,通过fbSdk实现了一种类似于微信朋友圈评论回复的功能。评论数据结构有几层未知,所以用到了递归。
递归组件,顾名思义,就是自己的内部实现又调用自己的组件。比如Vue官方给的treeView的例子,父目录下有子目录,子目录下还有子目录,子子孙孙,无穷尽也。就像俄罗斯套娃。


评论数据结构如上右图,层层嵌套。
封装递归组件👇


外部使用递归组件👇

二、应用场景
除此之外,递归组件应用场景也有很多,比如导航菜单。
三、递归组件模版
// example组件的实现 <template> <div> ... <Example></Example> ... </div> </template> <script> export default { name: 'Example' // 重要 } </script>
四、注意事项
除了前面所说的name选项是必须的之外,还有一点也是在实现递归组件要注意的,就是要防止无限递归,造成调用栈溢出。
上面说的子子孙孙,一直向下繁衍,可是浏览器受不了。这就要根据实际场景来分析递归的终止条件。
五、其他练习
接下来,我们来写一个递归组件。
下面的demo实现了一个模拟dom事件冒泡的操作,当点击中心圆时,事件逐级传递,然后改变div的颜色,直到冒泡到最顶层。
这里根据设置圆的数量进行递归,递归的终止条件是直到数量减到1。
<h3 style="text-align:center">点击中心圆查看效果</h3> <div id="app"> <colorful-circle :count="count"></colorful-circle> </div> <script type="text/x-template" id="circle-template"> <div class="colorful" :style="{ width: count * 60 + 'px', height: count * 60 + 'px', background: color }" @click="changeColor" > <colorful-circle v-if="count > 1" :count="count - 1" @colorChange="handleColor" ></colorful-circle> </div> </script>
html,body{ width: 100%; height: 100%; } .colorful{ display:flex; margin: 0 auto; transition: all .3s ease; align-items: center; justify-content: center; min-width 10px; border-radius: 50%; min-height: 10px; border: 1px solid #eaeaea }
var Color = net.brehaut.Color; function randomColor() { function randomNum(max) { return Math.floor(max * Math.random()); } return `rgb(${randomNum(256)},${randomNum(256)},${randomNum(256)})`; } Vue.component('colorful-circle', { data() { return { color: '' } }, props: { count: Number }, template: '#circle-template', mounted() { if (this.count === 1) { this.changeColor(); } }, methods: { handleColor(c) { this.color = Color(c).darkenByAmount( .05 ); setTimeout(() => { this.$emit('colorChange', this.color); },100); }, changeColor(e) { e && e.stopPropagation(); this.color = randomColor(); setTimeout(() => { this.$emit('colorChange', this.color); },100) } } }) new Vue({ el: '#app', data: { count: 7 } })

浙公网安备 33010602011771号