网站建设仟首先金手指13,辽宁平台网站建设平台,ui界面设计素材,怎么建立和设计公司网站一、大概流程 二、用到的Vue3知识
1、组件通信
#xff08;1#xff09;父给子
在vue3中父组件给子组件传值用到绑定和props
因为页签的数组要放在父页面中#xff0c; data(){return {tabs: []}},
所以顶部栏需要向父页面获取页签数组
先在页签页面中定义props用来接…一、大概流程 二、用到的Vue3知识
1、组件通信
1父给子
在vue3中父组件给子组件传值用到绑定和props
因为页签的数组要放在父页面中
data(){return {tabs: []}},
所以顶部栏需要向父页面获取页签数组
先在页签页面中定义props用来接收 props:{tabs: Array // 声明一个 props指定数据类型为数组},
再在父页面中的子页面标签中用:绑定符绑定 NavBar :tabstabs /NavBar
这样就可以将父页面的页签数组传到子页面里 2子给父
因为子页面中存在路由跳转新页面操作时候需要增加页签也就是将新的页面作为tab加入到页签数组中而页签数组放在父页面里所以需要子给父传值
子给父传值是通过调用方法实现用this.$emit(通信名,数据)实现
比如这里的添加页签操作则是 this.$emit(addtab,tab)然后在父页面的子标签里用接受通信名并绑定调用的方法 router-view addtabaddTab/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].selectedtrue;} 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 :tabstabs asideCollapsecollapse closetabcloseTab
5和有产生页签需求的子页面通信
router-view addtabaddTab/router-view2、顶部栏
1渲染页签 div classtop-bar!-- 渲染页签 --divv-for(tab, index) in tabs:keyindex:class[tab, { selected: tab.selected }]clickswitchTab(tab){{ tab.title }}span classclose-btn click.stopcloseTab(index)×/span/div/div
2编写页签样式
style langscss 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 clickaddTab({title: 模拟计算, // 页面标题route: /1/C, // 路由selected: true // 设置选中状态}) 四、展示效果 五、可能会出现的错误
1、在本地环境运行无错误部署到生产环境后会报
TypeError: Cannot read properties of null (reading insertBefore)的错误
解决方案
1NavBar顶部栏组件中v-for渲染tabs数组没有判断tabs是否为空
2切换vue为版本 (vue3.2.45) 来修复它。
npm i vue3.2.45