递归组件组合拳,无惧页面嵌套

介绍

递归组件在组件内嵌套组件时比较常用,我在这里举几个例子:

1、后台管理系统的menu菜单

2、教育系统的题目列表

在遍历生成基础题时,遇到了综合题,综合题包含了所有基础题,此时就不用再写一遍基础题,直接调用自身组件即可,这样不论基础题内部嵌套多少层综合题,都可以生成题目列表。


如何实现递归组件?

父页面:正常引入组件

javascript 复制代码
// 父页面
<template>
    <div>
        <Circulation :dataInfo="dataInfo"/>
    </div>
</template>
 
<script>
import Circulation from '@/views/circulation.vue'
export default {
    components: { Circulation },
    data() {
        return {
          dataInfo: [
            // ......
          ]
        }
    },
}
</script>

子组件

javascript 复制代码
// circulation页面
<template>
    <div>
       <div v-for="item in dataInfo"></div>
        // 其它逻辑......

        // 假如遇到children -> 复用自身 
        <Circulation :dataInfo="item.children"/>
    </div>
</template>
 
<script>
export default {
    name: 'Circulation', // 一定要设置name,于组件名相同
    props: {
        dataInfo: {
            type: Array,
            default: () => {
                return []
            }
        },
    },
}
</script>

上面的代码就实现了递归组件,在子组件中不需要引入自身,只需要设置name,然后通过name复用组件即可 下面是你在教育类型项目中会遇到的场景:


注意点

1、事件冒泡

注意:递归组件的事件一定要用.stop阻止冒泡,否则会报错 例如:@click.stop="onClose(item)"

2、prop值更新

在递归组件中通过事件更改prop的值时,会报错,提示请避免在子组件中对prop进行直接更改 Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "questionList" 避免直接更改 prop,因为每当父组件重新渲染时,该值都会被覆盖。相反,请使用基于道具值的数据或计算属性。被变异的道具:"questionList" 递归组件尽量避免直接对prop进行修改,哪怕你使用了计算属性,也会报错提示。

3、递归组件深层事件

由于是递归组件,层级的嵌套可能会很深,但是页面只有当前这一个,如果只处理当前层级的逻辑可以直接@click.stop="xxx"触发 如果需要将事件向父级回传,则需要使用emit,并且自身页面的递归组件上也需要设置事件,例如:

javascript 复制代码
// 父页面
<template>
    <div>
        <Circulation :dataInfo="dataInfo" @onChange="onChange"/>
    </div>
</template>
<script>
import Circulation from '@/views/circulation.vue'
export default {
    components: { Circulation },
    data() {
        return {
          dataInfo: [
            // ......
          ]
        }
    },
    methods: {
      // 触发事件 
      onChange() {},
    }
}
</script>

子页面

javascript 复制代码
// circulation页面
<template>
    <div>
       <div v-for="item in dataInfo"></div>
        // 其它逻辑......

        // 假如遇到children -> 复用自身 
        <Circulation :dataInfo="item.children"  @onChange="onChange"/>
    </div>
</template>
 
<script>
export default {
    name: 'Circulation', // 一定要设置name,于组件名相同
    props: {
        dataInfo: {
            type: Array,
            default: () => {
                return []
            }
        },
    },
    methods: {
      // 触发回传
      onChange() {
        this.$emit('onChange')
      },
    }
}
</script>

这样做它的回传事件会层层递归,直到返回最上层。 在渲染层面,它是层层递。 在事件回传层面,它是层层归。


如果觉得该组件不错,欢迎点赞👍、收藏💖、转发✨哦~

阅读其它:

微信小程序用户隐私API(👈点击直达)

前端换肤,聊一聊主题切换那些事(👈点击直达)

Shapes布局-文字环绕动画(👈点击直达)

css绘制一个Pinia小菠萝(👈点击直达)

深入理解Promise(👈点击直达)

相关推荐
雨季66622 分钟前
Flutter 三端应用实战:OpenHarmony 简易“动态内边距调节器”交互模式深度解析
javascript·flutter·ui·交互·dart
天人合一peng37 分钟前
Unity中button 和toggle监听事件函数有无参数
前端·unity·游戏引擎
会飞的战斗鸡1 小时前
JS中的链表(含leetcode例题)
javascript·leetcode·链表
方也_arkling1 小时前
别名路径联想提示。@/统一文件路径的配置
前端·javascript
毕设源码-朱学姐2 小时前
【开题答辩全过程】以 基于web教师继续教育系统的设计与实现为例,包含答辩的问题和答案
前端
qq_177767372 小时前
React Native鸿蒙跨平台剧集管理应用实现,包含主应用组件、剧集列表、分类筛选、搜索排序等功能模块
javascript·react native·react.js·交互·harmonyos
qq_177767372 小时前
React Native鸿蒙跨平台自定义复选框组件,通过样式数组实现选中/未选中状态的样式切换,使用链式调用替代样式数组,实现状态驱动的样式变化
javascript·react native·react.js·架构·ecmascript·harmonyos·媒体
web打印社区2 小时前
web-print-pdf:突破浏览器限制,实现专业级Web静默打印
前端·javascript·vue.js·electron·html
RFCEO2 小时前
前端编程 课程十三、:CSS核心基础1:CSS选择器
前端·css·css基础选择器详细教程·css类选择器使用方法·css类选择器命名规范·css后代选择器·精准选中嵌套元素
烬头88212 小时前
React Native鸿蒙跨平台采用了函数式组件的形式,通过 props 接收分类数据,使用 TouchableOpacity实现了点击交互效果
javascript·react native·react.js·ecmascript·交互·harmonyos