IT俱乐部 JavaScript vue3使用keep-alive组件,包含动态组件使用详解

vue3使用keep-alive组件,包含动态组件使用详解

vue3使用keep-alive组件,包含动态组件使用

组件不使用keep-alive

  • Father
Father change page
const cutTab = ref(false); const tabChange = () => { cutTab.value = !cutTab.value; }
  • Child
Child + {{ props.msg }}
const props = defineProps({ msg: { type: Boolean, default: false, }, }) const input = ref('')
  • Child2
Child2 + {{ props.msg }}
const props = defineProps({ msg: { type: Boolean, default: false, }, }) const input = ref('')

组件中使用

  • include:包含
  • exclude:排除

v-if切换

    
    

component动态组件切换

因注释导致的意外错误

expects exactly one child component

    

keep-alive组件内不要使用注释,会被解析为子节点

  • 添加div进行包裹
    
s
  • 移除注释
    

动态组件的使用

[Vue warn]: Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with ‘markRaw’ or using ‘shallowRef’ instead of ‘ref’.

在 Vue 3 中,如果用 ref 或 reactive 将一个组件包装成响应式对象,可能会引发不必要的性能开销。因为这会使 Vue 尝试去追踪组件的变化,而实际上组件实例并不需要被追踪。组件本身不应该是响应式的,只有它的 props 和 state 才应该是响应式的。

所以,当需要引用一个组件时,应该使用 shallowRef或者 markRaw,这样可以避免将整个组件变成响应式的,只会跟踪引用的变化

  • 使用markRaw
const com = ref(markRaw(Child2));

const comChange = () => {
  if(com.value === Child2){
    com.value = markRaw(Child);
  }else{
    com.value = markRaw(Child2);
  }
}
  • 使用shallowRef
const com = shallowRef(Child2);

const comChange = () => {
  if(com.value === Child2){
    com.value = Child;
  }else{
    com.value = Child2;
  }
}

完整示例

Father change component
import Child from "@/views/Child.vue"; import Child2 from "@/views/Child2.vue"; const cutTab = ref(false); const com = ref(markRaw(Child2)); const comChange = () => { if(com.value === Child2){ com.value = markRaw(Child); }else{ com.value = markRaw(Child2); } }

可以看到只有Child2组件是有缓存的,Child是有销毁和生成的

路由不使用keep-alive

  • 组件
Father
  • 路由index.ts
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'

const routes = [
  {
    path: '/Father',
    name: 'Father',
    component: () => import('@/views/Father.vue'),
    children: [
      {
        path: 'Child',
        name: 'Child',
        component: () => import('@/views/Child.vue'),
      },
      {
        path: 'Child2',
        name: 'Child2',
        component: () => import('@/views/Child2.vue'),
      }
    ],
  }, 
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

路由中使用

Vue Router 4(与 Vue 3 配套的路由库)引入了一个新的 API 来实现路由级别的 。这就是 组件的 v-slot API

  • 需要注意的是v-if不要加在keep-alive上,会直接销毁keep-alive,需要加在component
  • 实现页面部分刷新,页面进入时执行的生命周期为:created->mounted->activated
Father

路由index.ts

在对应的路由上添加meta属性来设置页面是否要使用缓存

...
const routes = [
  {
    path: '/Father',
    name: 'Father',
    component: () => import('@/views/Father.vue'),
    children: [
      {
        path: 'Child',
        name: 'Child',
        component: () => import('@/views/Child.vue'),
      },
      {
        path: 'Child2',
        name: 'Child2',
        meta: {
          keepAlive: true,  // 需要被keep-alive
        },
        component: () => import('@/views/Child2.vue'),
      }
    ],
  }, 
]
...

keep-alive生命周期

keep-alive组件会多出两个生命周期,分别在mounted之后和unMounted之前

onActivated(() => {
  console.log('Component is activated')
})

onDeactivated(() => {
  console.log('Component is deactivated')
})

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持IT俱乐部。

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/navsub/js/17842.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部