切换Tab页面不重复刷新页面/请求数据问题

需用到的点:Vue中的keepAlive内置组件+vue-router中的配置问题

  • 一、内置组件----keepAlive
    • 内部缓存机制
    • 钩子函数(生命周期)activated 和 deactivated
  • 二、 name属性及值
    • name属性的三种用途:
    • query传参和params传参的区别:
    • 组件在vue-router中引入组件的2种方式:

一、内置组件----keepAlive

Vue2官方文档:https://v2.cn.vuejs.org/v2/api/#keep-alive
Vue3官方文档:https://cn.vuejs.org/guide/built-ins/keep-alive.html

  • 作用:当多个组件(页面)之间进行切换时可对组件(页面)中的内容进行缓存,其内部存在缓存机制
  • 用法:
    • Vue2用法:
  <!-- App.vue中 -->
   <router-view v-else-if="isRouterAlive" v-slot="{ Component }">
      <keep-alive :include="['App']">
        <component :is="Component" />
      </keep-alive>
    </router-view>
  • Vue3用法:
   <!-- App.vue中 -->
    <template>
      <div id="app">
        <keep-alive >
          <router-view></router-view>
        </keep-alive>
      </div>
 </template>

内部缓存机制

组件默认是不存在缓存机制的,只要切换到下一个组件就会销毁当前的组件,此时可通过改内置组件将当前的组件进行销毁,内部缓存机制:

  1. 缓存所有界面
   <!-- App.vue中 -->
    <template>
      <div id="app">
        <keep-alive >
          <router-view></router-view>
        </keep-alive>
      </div>
 </template>
  1. 缓存部分页面
  • 使用$route.meta属性
  <!-- App.vue中 -->
    <template>
      <div id="app">
        <keep-alive >
          <router-view v-if="$route.meta.keepAlive"></router-view>   //需缓存的组件或者自定义
        </keep-alive>
        <router-view v-if="!$route.meta.keepAlive"></router-view>  //不需要缓存的组件
      </div>
    </template>
  • 或者在vue-router:router.ts/js中:,
  <!-- App.vue中 -->
    {
          path: '/basis/drps/department',
          name: 'about',
          component: () =>
            import(
              /* webpackChunkName: "ums-department" */ '@/views/user/department/about.vue' ),
          meta: {
            keepalive: true, //默认未false,若为true则表示该页面需要缓存
          },
        },
  • 在Vue2中:存在 include 和 exclude 及 max(最多缓存多少组件)
<!-- include是包含 使用的是组件名(组件中的name非路由中的name)并非是路由的名字 此处只有Hello组件有缓存 -->
<keep-alive include="Hello">
   <router-view></router-view>
</keep-alive>
<!-- exclude是不包含/排除 使用的是组件名(组件中的name非路由中的name)并非是路由的名字 此处只有Hello组件不被缓存 其他都能被缓存-->
<keep-alive exclude="Hello">
   <router-view></router-view>
</keep-alive>
<!-- max最大 此处最多缓存10个组件-->
<keep-alive :max="10">
  <component :is="view"></component>
</keep-alive>

钩子函数(生命周期)activated 和 deactivated

  • 作用:用于保留组件状态或者是避免重新渲染
  • 渲染时机:首次进入created->mounted->activated,退出当前组件时执行deactivated,再进入只触发activated
  • 注意:事件只执行一次放在mounted中,每次进入都执行则放在activated中
<!-- activated:进入页面时执行->
activated(){
 
},
<!-- deactivated:退出页面时执行->
deactivated(){
 
},

二、 name属性及值

name属性的三种用途:

  • (1)可通过name属性在一个页面中的使用渲染其他组件:
<!-- about.vue -->
<router-view name = 'Hello'/> // 在about组件中渲染Hello组件
  • (2)name可进行路由传参,可使用$router.name获取组件中的name值:
<h1>{{$router.name}}</h1> // 渲染组件中name的值
  • (3)路由的传参:可用于params(query)传参,params必须使用name,而query可使用name或者path:
<!-- params传参 1、声明式: router-link-->
//父路由组件
<router-link :to="/child/123">进入Child路由</router-link>
//子路由配置
{
 path: '/child/:id',
 component: Child
}
// 或者
{
 path: '/child/:id',
 name:"Child",
 component: Child
}
<!-- params传参 2、编程/链式:this.$router.push-->
// 父路由使用编程式进行传参(通常使用事件触发)
this.$router.push({
    path:'/child/${id}',
})
//子路由配置
{
  path: '/child/:id',
  component: Child
}
//子路由中可通过this.$route.params.id进行获取
<!-- query传参 1、声明式:-->
// 父路由组件中
<router-link :to="{name:'Child',query:{id:134565}}">进入到Child路由中</router-link>
// 子路由配置
{
  path: '/child,
  name: 'Child',
  component: Child
}
// 父路由通过编程式传参(通常是通过事件进行触发)
this.$router.push({
    name:'Child',
    query:{
    	id:123
    }
})
// 子路由配置
{
  path: '/child,
  name: 'Child',
  component: Child
}
//子路由中可通过this.$route.query.id获取到所传递的参数

query传参和params传参的区别:

  1. params传参:只能用 name,不能用 path,且地址栏中不显示参数名,但是存在参数的值
  2. query传参:name 和 path 都可以用;使用 path 的时,所提供的 path 值必须是当前根目录下的相对路径,而不是相对于父路由的相对路径,且地址栏中显示参数名,其格式为:?id=1345646&code=10212

组件在vue-router中引入组件的2种方式:

  • (1)组件的引入及起别名形式:
<!-- router.js/ts中 -->
import About from '@views/about/about.vue'

const aboutRouter = {
  path: '/about',
  name:'About', //此处的About必须与about.vue页面中的name值相同,否则即使配置了keepalive:true也无效
  component: About,
  meta: {
    keepalive: true,
  },
<!-- about.vue中 -->
export default defineComponent({
  name: 'About', //当前页面的名字,namespace
  ...
});
  • (2)组件直接引入
const aboutRouter = {
  path: '/about',
  name:'About', //此处的About必须与about.vue页面中的name值相同,否则即使配置了keepalive:true也无效
  component: () => import('@/views/about.vue'),
  meta: {
    keepalive: true,
  },
<!-- about.vue中 -->
export default defineComponent({
  name: 'About', //当前页面的名字,namespace
  ...
});
  • (3)总结:若要保持Tab进行切换时页面不重复进行刷新:需router.js/ts中的name = component的名字/路径 = xx.vue页面中的name

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