Vue3项目重复点击菜单,刷新页面
一般来讲,重复点击Menu,是不刷新页面的,这是由于Vue的路由机制是路由不变的情况下,对应的组件是不重新渲染的,但如果有刷新的需求,也是可以做的
思路: 改变路由
方案一(推荐):利用v-if原理重载路由
default.vue
<template>
<div id="app">
<asider @router-reload="reload"></asider>
<router-view v-if="isRouterAlive"></router-view>
</div>
</template>
<script lang="ts">
import { defineComponent,nextTick,reactive,toRefs } from "vue";
import Asider from './asider.vue';
export default defineComponent({
name: 'App',
components: { Asider },
setup(){
const data = reactive({
isRouterAlive: true
})
const reload = () => {
data.isRouterAlive = false
nextTick(() => {
data.isRouterAlive = true
})
}
return {
...toRefs(data),
reload
};
}
})
</script>
<style>
</style>
asider.vue
<template>
<a-menu
v-model:openKeys="openKeys"
v-model:selectedKeys="selectedKeys"
mode="inline"
@click="handleAsideClick"
>
<template v-for="item in menu" :key="item.key">
<--利用路由名作为菜单的key-->
<a-menu-item v-if="!item.children || !item.children.length" :key="item.router_name">
{{item.name}}
</a-menu-item>
<a-sub-menu v-else :key="item.id">
<template #title>{{item.name}}</template>
<a-menu-item v-for="inner item.children" :key="inner.router_name" >
<span>{{inner.name}}</span>
</a-menu-item>
</a-sub-menu>
</template>
</template>
<script lang="ts">
import { defineComponent,computed,reactive,toRefs } from "vue";
import {
useCacheStore,
} from '@/store/modules/app'
export default defineComponent({
name: 'asider',
setup(props, ctx){
const cacheStore = useCacheStore()
const menuKey = computed(() => cacheStore.menuKey) // store中存着的当前展示的菜单
const data = reactive({
})
// 如果点击的是新的菜单,则跳转
// 如果点击的还是上一次的菜单,则重载路由
const handleAsideClick= ({ key }) => {
if(menuKey.value=== key){
ctx.emit('router-reload')
} else {
cacheStore.setMenuKey(key) // 设置菜单key
router.push({name: key})
}
}
return {
...toRefs(data),
handleAsideClick
};
}
})
</script>
提醒: provide和inject也可以用
方案二:给路由添加唯一的key
利用router.fullPath作为唯一的key,vue就会认为是不同的路由,每次都会跳转成功并刷新组件
缺点:携带了一些不必要的参数
<template>
<div id="app">
<router-view :key="route.fullPath"></router-view>
</div>
</template>
import { defineComponent,nextTick,reactive,toRefs } from "vue";
import { useRouter, useRoute } from "vue-router";
export default defineComponent({
name: 'App',
setup(){
const route = useRoute();
return {
route
};
}
})
</script>
// asider.vue
const handleAsideClick = ({key}) => {
router.push({name: key, query: {
id: Math.ceil(Math.random()*100)
}
})
}