vue3 keep-alive 实现页面标签

vue3 keep-alive 实现页面标签

一、简单效果图展示

在这里插入图片描述

二、项目搭建

注:如果已有项目可直接跳过
简单项目搭建如下步骤(文中使用的是vue-cli快速搭建项目):vue-cli官网链接: link(点击跳转)

  1. 安装Vue CLI(具体步骤看官网),这里注意安装最新版的cli就好;
  2. 用cli快速生成项目:注意:这里要选中 Manually select features 这个选项
    项目快速生成配置
  3. 选择自己需要的插件,文中用到的有vuex、router、css(按下键,空格选中,回车下一步)第三步
  4. 接下来会选择使用vue2 还是vue3 ,如果选择了css还会选择使用sass还是less还是Stylus
  5. 上面的步骤完成了可以直接回车生成项目

三、keep-alive 页面标签简单实现

router.js 路由路径设置

{
    path: "/",
    name: "home",
    redirect: "/home", //重定向到home页面
    children: [
      {
        path: "/home",
        name: "HomeView",//注意如果需要换成,name必须是唯一的并且和compnent对应的vue文件中的name一致。
        component: () =>
          import(/* webpackChunkName: "HomeView" */ "@/views/HomeView.vue"),//这里用了vue cli的懒加载 
        meta: {
          title: "首页",
          keepAlive: true,//meta路由元配置是否需要keep-alive缓存
        },
      },
      .......这里根据自己的项目要求设置
   ]
}
//路由进入之前的钩子函数
router.beforeEach((to, from, next) => {
  window.document.title = to.meta.title;//这里设置浏览器的title,如果不需要刻意去掉
  to.meta.keepAlive ? store.commit("setLabelDataList", to) : "";//这里的逻辑是为了在打开页面前将路由route的name存入vuex中,方便管理
  next();
});

vuex

export default createStore({
  state: {
    labelDataList: [], //存放打开的路由标签页
  },
  mutations: {
  //打开新的页面的时候将页面的信息存到vuex里面
    setLabelDataList(state, data) {
      let boo = state.labelDataList.find((item) => {
        return item.name == data.name;
      });
      if (!boo) {
        state.labelDataList.push({
          name: data.name,
          path: data.path,
          title: data.meta.title,
        });
      }
    },
    //当标签关闭的时候删除labelDataList 对应的数据
    setDeleteLabelDataList(state, index) {
      console.log(index);
      state.labelDataList.splice(index, 1);
    },
  },
  actions: {}, //通过mutations提交 可以是异步的
});

简单的业务实现

  1. 在需要的地方加入keep-alive标签,如下:
    <router-view v-slot="{ Component }">
    	<keep-alive :include="labelDataName">
    		注意这里的key必须是唯一的 否则缓存会失效
    		这里也是vue2(不需要key) 与vue3的区别
    		<component :is="Component" :key="$route.name" />
    	</keep-alive>
    	<component
    	:is="Component"
    	v-if="!labelDataName.includes($route.name)"
    	/>
    </router-view>
    
    setup() {
        const store = useStore();
        let labelDataName = computed(() => {
          //从vuex中取出需要换成的标签名,利用keep-alive的includea api缓存我们需要缓存的页面
          return store.state.labelDataList.map((e) => e.name);
        });
        return {
          labelDataName,
        };
    },
    
  2. 最后实现页面标签
    <div class="label" v-for="(item, index) in labelDataList" :key="item.name">
       <a>
         <router-link :to="item.path">{{ item.title }}</router-link>
       </a>
       <a class="delete" @click="close(item, index)" v-if="item.path != '/home'"
         >x</a
       >
    </div>
    import { useStore } from "vuex";
    import { useRoute, useRouter } from "vue-router";
    setup() {
      const store = useStore();
      const route = useRoute();
      const router = useRouter();
    
      let labelDataList = computed(() => {
        return store.state.labelDataList;
      });
      const close = (item, index) => {
        store.commit("setDeleteLabelDataList", index);
        if (route.path === item.path) {
          router.push("/home");
        }
      };
      return { labelDataList, close };
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值