Vue3 用父子组件通信实现页面页签功能

一、大概流程

Vue3 用父子组件通信实现页面页签功能_第1张图片

二、用到的Vue3知识

1、组件通信

(1)父给子

在vue3中父组件给子组件传值用到绑定和props

因为页签的数组要放在父页面中,


  data(){
    return {
      tabs: []
    }
  },

所以顶部栏需要向父页面获取页签数组

先在页签页面中定义props用来接收

  props:{
    tabs: Array // 声明一个 props,指定数据类型为数组
  },

再在父页面中的子页面标签中用:绑定符绑定

  

这样就可以将父页面的页签数组传到子页面里

(2)子给父

因为子页面中存在路由跳转新页面操作时候需要增加页签,也就是将新的页面作为tab加入到页签数组中,而页签数组放在父页面里,所以需要子给父传值

子给父传值是通过调用方法实现用this.$emit("通信名",数据)实现

比如这里的添加页签操作则是

     this.$emit("addtab",tab)

然后在父页面的子标签里用@接受通信名并绑定调用的方法,

 

 同时将数据作为data参数传入方法

    addTab(data) {
      //最简单的push操作,还没完成其它逻辑
      this.tabs.push(data);

    }

三、实现整体逻辑

1、父页面中

(1)编写增加页签的逻辑

    addTab(data) {
      // this.tabs.push(data);
        // 判断是否已存在相同的 title 和 route
        const 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);
      }
    },
  }

缓存页签数据到浏览器,页面刷新时,页签状态保留当前状态不会清空

Vue3 用父子组件通信实现页面页签功能_第2张图片

(4) 和顶部栏通信

(5)和有产生页签需求的子页面通信


2、顶部栏

(1)渲染页签

    
{{ tab.title }} ×

(2)编写页签样式

(3)接受父页面数据

  props:{
    tabs: Array // 声明一个 props,指定数据类型为数组
  },

(4)向父页面发送关闭页签请求

    // 关闭页签
    closeTab(index) {
      this.$emit("closetab",index)
    },

3、子页面

(1)向父页面发送增加页签请求

  methods:{
   addTab(tab){
     this.$emit("addtab",tab)
   }

  }

 (2)在有跳转路由的需求的标签绑定请求

  比如菜单项

        

四、展示效果

Vue3 用父子组件通信实现页面页签功能_第3张图片

五、可能会出现的错误

1、在本地环境运行无错误,部署到生产环境后会报

TypeError: Cannot read properties of null (reading 'insertBefore')的错误

解决方案 

(1)NavBar顶部栏组件中v-for渲染tabs数组没有判断tabs是否为空

(2)切换vue为版本 ([email protected]) 来修复它。

npm i [email protected]

你可能感兴趣的:(vue.js,前端,javascript)