Vue3 用父子组件通信实现页面页签功能
一、大概流程

二、用到的Vue3知识
1、组件通信
(1)父给子
在vue3中父组件给子组件传值用到绑定和props
因为页签的数组要放在父页面中,
data(){return {tabs: []}},
所以顶部栏需要向父页面获取页签数组
先在页签页面中定义props用来接收
props:{tabs: Array // 声明一个 props,指定数据类型为数组},
再在父页面中的子页面标签中用:绑定符绑定
<NavBar :tabs="tabs" ></NavBar>
这样就可以将父页面的页签数组传到子页面里
(2)子给父
因为子页面中存在路由跳转新页面操作时候需要增加页签,也就是将新的页面作为tab加入到页签数组中,而页签数组放在父页面里,所以需要子给父传值
子给父传值是通过调用方法实现用this.$emit("通信名",数据)实现
比如这里的添加页签操作则是
this.$emit("addtab",tab)
然后在父页面的子标签里用@接受通信名并绑定调用的方法,
<router-view @addtab="addTab"></router-view>
同时将数据作为data参数传入方法
addTab(data) {//最简单的push操作,还没完成其它逻辑this.tabs.push(data);}
三、实现整体逻辑
1、父页面中
(1)编写增加页签的逻辑
addTab(data) {// this.tabs.push(data);// 判断是否已存在相同的 title 和 routeconst exists = this.tabs.some(tab => tab.title === data.title && tab.route === data.route);if (!exists) {this.tabs.forEach(tab => {tab.selected = false;});this.tabs.push(data);}else{this.tabs.forEach(tab => {tab.selected = tab.title === data.title && tab.route === data.route;});}// 更新浏览器缓存this.saveTabsToLocalStorage()}
(2)编写关闭页签的逻辑
closeTab(index) {this.tabs.splice(index, 1); // 从数组中移除页签if (this.tabs.length > 0) {this.tabs.forEach(tab => {tab.selected = false;});// 如果还有其他选项卡,跳转到最后一个选项卡的路由const lastTab = this.tabs[this.tabs.length - 1];this.$router.push(lastTab.route);this.tabs[this.tabs.length - 1].selected=true;} else {// 如果没有选项卡了,跳转到默认的首页路由this.$router.push("/1/C");}// 更新浏览器缓存this.saveTabsToLocalStorage()},
(3)页签数组缓存到浏览器和从缓存加载
mounted() {this.loadTabsFromLocalStorage();},methods:{// 缓存到本地saveTabsToLocalStorage() {localStorage.setItem('tabs', JSON.stringify(this.tabs));},// 从缓存加载loadTabsFromLocalStorage() {const storedTabs = localStorage.getItem('tabs');if (storedTabs) {this.tabs = JSON.parse(storedTabs);}},}
缓存页签数据到浏览器,页面刷新时,页签状态保留当前状态不会清空

(4) 和顶部栏通信
<NavBar :tabs="tabs" @asideCollapse="collapse" @closetab="closeTab">
(5)和有产生页签需求的子页面通信
<router-view @addtab="addTab"></router-view>
2、顶部栏
(1)渲染页签
<div class="top-bar"><!-- 渲染页签 --><divv-for="(tab, index) in tabs":key="index":class="['tab', { 'selected': tab.selected }]"@click="switchTab(tab)">{{ tab.title }}<span class="close-btn" @click.stop="closeTab(index)">×</span></div></div>
(2)编写页签样式
<style lang="scss" scoped>.top-bar{display: flex;margin-left: 20px;caret-color: transparent; /*去除鼠标光标*/width: 100vw;overflow-x: auto; /* 允许横向滚动 *///overflow: hidden;div:hover{cursor:pointer;}div:not(:first-child){margin-left: 10px;}div{display: flex;justify-content: center;align-items: center;padding: 5px;font-weight: 500;font-size: 14px;color: #606266;border: 1px solid #DCDFE6;border-radius: 4px;//width: 100%;height: 30px;white-space: nowrap; /* 防止内容换行 */span{width: 15px;height: 15px;margin-left: 4px;display: flex;align-items: center;justify-content: center;}}.tab{background-color: #eeeeee;span:hover{background: linear-gradient(rgba(96, 98, 102, 0.1), rgba(96, 98, 102, 0.1)); /* 在悬停时更改透明度 */}}.selected{background-color: #c6fce5;}
}</style>
(3)接受父页面数据
props:{tabs: Array // 声明一个 props,指定数据类型为数组},
(4)向父页面发送关闭页签请求
// 关闭页签closeTab(index) {this.$emit("closetab",index)},
3、子页面
(1)向父页面发送增加页签请求
methods:{addTab(tab){this.$emit("addtab",tab)}}
(2)在有跳转路由的需求的标签绑定请求
比如菜单项
<el-menu-item index="/1/C" @click="addTab({title: '模拟计算', // 页面标题route: '/1/C', // 路由selected: true // 设置选中状态})">
四、展示效果

五、可能会出现的错误
1、在本地环境运行无错误,部署到生产环境后会报
TypeError: Cannot read properties of null (reading 'insertBefore')的错误
解决方案
(1)NavBar顶部栏组件中v-for渲染tabs数组没有判断tabs是否为空
(2)切换vue为版本 (vue@3.2.45) 来修复它。
npm i vue@3.2.45
相关文章:
Vue3 用父子组件通信实现页面页签功能
一、大概流程 二、用到的Vue3知识 1、组件通信 (1)父给子 在vue3中父组件给子组件传值用到绑定和props 因为页签的数组要放在父页面中, data(){return {tabs: []}}, 所以顶部栏需要向父页面获取页签数组 先在页签页面中定义props用来接…...
HCIP STP协议
STP协议 STP协议概念生成树为什么要用STP STP名词解释根网桥根端口指定端口非指定端口 STP的版本802.1DPVSTPVST 快速生成树 STP协议概念 IEEE 802.1d STP(生成树协议,Spanning-Tree Protocol)协议: ①使冗余端口置于“阻塞状态”…...
链表的顶级理解
目录 1.链表的概念及结构 2.链表的分类 单向或者双向 带头或者不带头 循环或者非循环 3.无头单向非循环链表的实现 3.1创建单链表 3.2遍历链表 3.3得到单链表的长度 3.4查找是否包含关键字 3.5头插法 3.6尾插法 3.7任意位置插入 3.8删除第一次出现关键字为key的节点 …...
探索贪心算法:理解与实现JAVA语言
探索贪心算法:理解与实现 贪心算法(Greedy Algorithm)是一种基于每一步的最优选择来达到整体最优的算法思想。尽管贪心算法并不适用于所有问题,但它在很多情况下都能够提供高效、近似的解决方案。本文将深入探讨贪心算法的基本概…...
数字孪生技术对旅游行业能起到什么作用?
随着疫情对我们生活影响的淡化,旅游行业迎来了新的春天,暑期更是旅游行业的小高潮,那么作为一个钻研数字孪生行业的小白,本文就着旅游的话题以及对旅游的渴望带大家一起探讨一下数字孪生对智慧旅游发展的作用~ 数字孪生作为一种虚…...
攻防世界-Web_php_include
原题 解题思路 php://被替换了,但是只做了一次比对,改大小写就可以绕过。 用burp抓包,看看有哪些文件 flag明显在第一个PHP文件里,直接看...
Python Opencv实践 - 直方图显示
import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) print(img.shape)#图像直方图计算 #cv.calcHist(images, channels, mask, histSize, ranges, hist, accumulate) #images&…...
2分钟搭建自己的GPT网站
如果觉得官方免费的gpt(3.5)体验比较差,总是断开,或者不会fanqiang,那你可以自己搭建一个。但前提是你得有gpt apikey。年初注册的还有18美金的额度,4.1号后注册的就没有额度了。不过也可以自己充值。 有了…...
deepdiff比较两个json文件数据差异性
deepdiff比较两个json文件数据差异性 Python代码片: import json import sysfrom deepdiff import DeepDiff from deepdiff import grep, DeepSearch from deepdiff import DeepHash# print(DeepDiff("abc", "abcd", ignore_orderTrue))class …...
文件内容搜索工具 - Python实现
在本篇文章中,我们将介绍如何使用 wxPython 库创建一个简单的文件搜索工具。这个工具允许用户选择一个文件夹,并在该文件夹中的所有 .py 文件中查找指定的文字,并显示匹配的位置。 C:\pythoncode\blog\searchwordinpyfile.py 代码实现 我们首…...
vue静态html加载外部组件
当我们在开发vue应用时, 使用的是html页面开发, 需要引用外部vue组件, 怎么办呢, 首先我们引用http-vue-loader.js文件, 像下面这样: <script src"/assets/javascript/vue.min.js"></script> <script src"/assets/javascript/http-vue-loader.j…...
WebSocket 中的心跳是什么,有什么作用?
在网络应用开发中,WebSocket 是一种重要的通信协议,它允许客户端和服务器之间建立持久性的双向通信连接。然而,为了保持连接的稳定性,WebSocket 中的心跳是一个不可或缺的概念。本文将详细介绍 WebSocket 中的心跳是什么ÿ…...
Android类加载机制
要说Android的类加载机制 ,就离不开 类加载器ClassLoader,它是一个抽象接口 下面这个图还是比较好表达了类加载流程,但如果不看我红色画的线,就会感觉有点乱,需要注意是采用的是双亲委派模式,class加载要先…...
微信小程序列表加载更多
概述 基于小程序开发的列表加载更多例子。 详细 一、前言 基于小程序开发的列表加载更多例子。 二、运行效果 运行效果(演示的小视频,点击播放即可) 三、实现过程 总体思路如何: 1、通过scroll-view组件提供的bindscroll方法…...
数据库知识
怎么做 常见的数据库 Oracle Mysql SOLSever Navicat (新版可以链接mysql oracle) http://sqlfiddle.com/ 数据库操作在线练习 mysql自带四个数据库 数据库语言的使用 显示数据库:show databases; 创建数据库:…...
VUE 目录介绍
更新升级(npm - i)之后最终目录如下: total 1672 drwxr-xr-x 18 testrose staff 576 8 22 02:53 . drwxr-xr-x 24 testrose staff 768 8 22 02:50 .. -rw-r--r-- 1 testrose staff 402 8 22 02:52 .babelrc -rw…...
Selenium的基本使用
文章目录 引入一.选择元素的基本方法1.根据id 选择元素2.根据 class属性选择元素当元素有 多个class类型 时 3.根据 tag名 选择元素4.通过WebElement对象选择元素5.find_element 和 find_elements 的区别 二.等待界面元素出现1.隐式等待2.显示等待 三.操控元素的基本方法1.点击…...
数据结构-----树的易错点
1.树的度和m叉树 •度为m的树(度表示该结点有多少个孩子(分支)) 任意结点的度<m(最多m个孩子) 至少又一个结点度m(有m个孩子) 一定是非空树,至少有m1个结点 •m叉树 任意结点的度<m(最多有m个孩子) 允许所…...
写之前的项目关于使用git remote -v 找不到项目地址的解决方案
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、报错解析1. 报错内容2. 报错翻译3. 报错解析(1)使用git branch来查看git仓库有几个分支(2)使用git remote -v&am…...
STM32 F103C8T6学习笔记9:0.96寸单色OLED显示屏—自由取模显示—显示汉字与图片
今日学习0.96寸单色OLED显示屏的自由取模显示: 宋体汉字比较复杂,常用字符可以直接复制存下来,毕竟只有那么几十个字母字符,但汉字实在太多了,基本不会全部放在单片机里存着,一般用到多少个字就取几个字的模ÿ…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
