vue3使用keep-alive缓存已打开过的菜单,使用el-tabs展示面包屑路由。

vuex

import { debug } from "console";
import { createStore } from "vuex";
let availButtons = new Set();
export default createStore({
    state: {
        count: 0,
        tabsList: [
            {
                path: "/",
                name: "Profile",
                meta: {
                    title: "首页",
                },
            },
        ],
        keepAliveList: ["Profile"],
        currentMenu: null,
        menu: [],
        //  按钮权限
        buttons: availButtons,
    },
    mutations: {
        // 判断按钮是否有权限
        setButtons(state, payload) {
            state.buttons = payload.buttons;
        },
      
        // 选择标签 选择面包屑
        selectMenu(state, val) {
            console.log({ val });
            if (val.path === "/") {
                // state.currentMenu = null;
            } else {
                // state.currentMenu = val.name;
                let result = state.tabsList.findIndex(
                    (item) => item.name === { ...val }.name
                );
                if (result === -1) {
                    state.tabsList.push({ ...val });
                }
                // debugger;
            }
        },
        closeTab(state, val) {
            let result = state.tabsList.findIndex(
                (item) => item.name === val.name
            );
            state.tabsList.splice(result, 1);
            state.keepAliveList.length = 0;
            state.tabsList.forEach((item) => {
                state.keepAliveList.push(item.name);
            });
        },
        updateKeepList(state, val) {
            let index = state.keepAliveList.findIndex(
                (item: any) => item.name === val.name
            );
            if (index === -1) {
                state.keepAliveList.push(val.name);
            }
        },
    },
    actions: {
        
    },
    getters: {
      
        
    },
});

component/CommonTab.vue

<template>
  <div class="tabs">
    <el-tabs
      v-model="currentName"
      type="card"
      editable
      @tab-remove="handleTabsEdit"
      @tab-click="handleTabClick"
    >
      <el-tab-pane
        editable
        :key="tag.meta.title"
        v-for="tag in tags"
        :label="tag.meta.title"
        :name="tag.meta.title"
      >
      </el-tab-pane>
    </el-tabs>
    <div>{{ tags }}</div>
  </div>
</template>
<script setup lang="ts">
import * as Utils from "@/utils";
import { mapState, mapMutations, useStore } from "vuex";
import { ref, reactive, onMounted, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
const currentName = ref("首页");
const tags = ref([]);
const store = useStore();
const router = useRouter();
const route = useRoute();
onMounted(() => {
  tags.value = store.state.tabsList;
  watch(
    () => route.path,
    () => {
      currentName.value = route.meta.title as string;
    },
    { immediate: true, deep: true }
  );
});
function handleClose(tag: any, index: any) {
  let length = tags.value.length - 1;
  store.commit("closeTab", tag);
  if (tag.name !== route.name) {
    return;
  }
  if (index === length) {
    router.push({ path: tags.value[index - 1].path });
  } else {
    router.push({ path: tags.value[index].path });
  }
}
function changeMenu(item: any) {
  let params = {
    path: route.path,
    name: route.name,
    meta: {
      title: route.meta.title,
    },
  };
  store.commit("selectMenu", params);
}
function handleTabsEdit(targetName: any, action: any) {
  let result = tags.value.findIndex(
    (item: any) => item.meta.title === targetName
  );
  handleClose(tags.value[result], result);
}
function handleTabClick(tab: any) {
  let result = tags.value.findIndex(
    (item: any) => item.meta.title === currentName.value
  );
  changeMenu(tags.value[result]);
  router.push({ path: tags.value[result].path });
}
</script>
<style lang="scss">
.tabs {
  line-height: 50px;
  margin-left: 18px;
  text-align: left;
  .el-tag {
    margin-right: 5px;
    cursor: pointer;
  }
  .dark {
    background: #409eff;
    border-color: #409eff !important;
    color: #fff !important;
    .el-tag__close {
      color: #fff !important;
    }
  }
  .plain {
    background: #fff;
  }
  .el-tag {
    color: #333;
    .el-tag__close {
      color: #333;
      &:hover {
        background: #cbcbce;
        font-weight: bolder;
      }
    }
    border-color: rgb(207, 204, 204);
  }
}
</style>

vue3使用keepalive写法有变化。

<router-view v-slot="{ Component }">
  <keep-alive :include="store.state.keepAliveList">
    <component :is="Component" :key="route.path" />
  </keep-alive>
</router-view>
菜单点击事件也有变化,获取的路由的上一次的路由,所以需要从菜单渲染中拿到数据。
与keepaliveList.keyValue一一对应。
const menuItemClick = (item: any) => {
  const current = router;
  let params = {
    path: item.path,
    name: item.routeName,
    meta: {
      title: item.name,
    },
  };
  store.commit("selectMenu", params);
  store.commit("updateKeepList", params); 
};
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3中,使用keep-alive组件缓存页面并不会停留在阅读位置。keep-alive组件是用来缓存动态组件或者是router-view中的组件,以便在切换路由或者是组件时能够保留组件的状态,以提高页面渲染效率。 然而,keep-alive并不会在缓存组件之间进行滚动位置的记忆。当一个组件被缓存并再次被激活时,Vue3仍然会将其放置在初始位置,而不是在之前滚动的位置。这是keep-alive的默认行为。 如果希望在缓存组件之间保留滚动位置,可以通过自定义实现。一种常见的方法是使用Vue的导航守卫和ref属性来实现。在导航守卫的beforeRouteLeave中记录当前组件的滚动位置,然后在activated生命周期钩子中恢复滚动位置。 具体实现步骤如下: 1. 在组件中定义一个ref属性用来保存滚动位置,例如:scrollRef。 2. 在beforeRouteLeave导航守卫中使用document.documentElement.scrollTop或者document.body.scrollTop来获取当前的滚动位置,并将其赋值给scrollRef。 3. 在activated生命周期钩子中使用document.documentElement.scrollTop或者document.body.scrollTop来设置滚动位置为scrollRef的值。 这样,每当缓存组件再次被激活时,Vue3会自动将滚动位置恢复到之前记录的位置,从而实现在缓存组件之间保留滚动位置的效果。 总结来说,Vue3的keep-alive组件在缓存并重用组件时不能自动保存滚动位置,但可以通过自定义实现来实现此功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值