vue 动态组件+全局组件+keepAlive

vue 动态组件+全局组件+keepAlive

故心故心故心故心小故冲啊



动态模板

当在这些组件之间切换的时候,有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题

1、通过条件匹配来显示
<button @click="flag='testA'">A组件</button>
<button @click="flag='testB'">B组件</button>
<testA v-if="flag=='testA'"></testA>
<testB v-if="flag=='testB'"></testB>
2、动态模板

vue中提供了一个动态模板,可以在任意模板中切换,就是用vue中用:is来挂载不同的组件。

<component :is="flag"></component> 

import testA from './testA.vue'; //导入
import testB from './testB.vue'; //导入

data(){
    return{
      flag:'testA', 
    }
}
3、异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义

非异步组件加载,提前加载
import testA from './testA'; 
import testB from './testB';  

components: {
    testA,  
    testB
},
异步组件
components: {
    //不会提前加载,在需要用到的时候才会加载组件
    //异步解析组件  当使用局部注册的时候,你也可以直接提供一个返回 Promise 的函数
    'testB': () => import('./testB')   
},
全局组件定义

在我们项目开发中,经常需要import或者export各种模块,那么有没有什么办法可以简化这种引入或者导出操作呢

import A from 'components/A'
import B from 'components/B'
import C from 'components/C'
import D from 'components/D'
......

这样很头疼,因为每加一个组件,都要写这么一句,有规律的事,是否可以通过自动化完成呢

定义全局组件的方式:

Vue.component('myComponent', {render(){return <h1>hello world</h1>}})

webpack中require.context

require.context(directory, useSubdirectories, regExp)
  1. directory: 要查找的文件路径
  2. useSubdirectories: 是否查找子目录
  3. regExp: 要匹配文件的正则

用法:

require.context('./', true, /\.js$/);

定义全局自定义组件

// 引入全局自定义组件
import './components/global'
import Vue from 'vue'
const componentsContext = require.context('./', true, /\.js$/);

componentsContext.keys().forEach(component => {
    const componentConfig = componentsContext(component)
    // 兼容import export和require module.export两种规范
    const ctrl = componentConfig.default || componentConfig;
    // 加载全局组件
    if (ctrl && ctrl.name) {
        Vue.component(ctrl.name, ctrl);
    }
})

代码分析:

const componentsContext = require.context('./', true, /\.js$/);

//返回的是webpackContext方法
webpackContext(req) {
	var id = webpackContextResolve(req);
	return __webpack_require__(id);
}
componentsContext.keys()

//当前目录下所有的js文件
0: "./index.js"
1: "./my-banner/index.js"
2: "./my-button/index.js"
3: "./my-button2/index.js"

全局组件的定义:

index.js
import main from './main.vue'
export default main

main.vue
<template>
    <div>我的按钮</div>
</template>

<script>
export default {
    name: 'my-button',
    data(){
        return {}
    }
}
</script>

这样其它页面就可以直接引用了

<my-button />
组件缓存 keep-alive

每次切换新标签的时候,Vue 都创建了一个新的实例。

重新创建动态组件的行为通常是非常有用的,如果希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive>元素将其动态组件包裹起来。

keep-alive是Vue提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,

所以在页面渲染完毕后不会被渲染成一个DOM元素

include: 只有匹配的组件才会缓存,符合条件:字符串/正则

exclude: 任何组件都不会缓存,符合条件:字符串/正则

<button @click="flag='testA'">a</button>
<button @click="flag='testB'">b</button>
<button @click="flag='testC'">c</button>

import testA from './testA.vue'; //导入
import testB from './testB.vue'; //导入
import testC from './testC.vue'; //导入

data(){
    return{
      flag:'testA'
    }
  },
只有组件testA才会缓存
<keep-alive include='testA'>
		<component :is="flag"></component>
</keep-alive>
组件testA,testB才会缓存
<keep-alive include='testA,testB'>
	<component :is="flag"></component>
</keep-alive>
除了组件testA,testC缓存
<keep-alive exclude='testA,testC'>
	<component :is="flag"></component>
</keep-alive>

对于路由切换后想缓存组件的状态,这种如何处理咧?

<keep-alive>
	<!-- 这里是会被缓存的视图组件 -->
	<router-view v-if="$route.meta.keepAlive" />
</keep-alive>

<!-- 这里是不被缓存的视图组件-->
<router-view v-if="!$route.meta.keepAlive" />

路由中的定义
const routes = [
  {
    path: '/',
    redirect:'/about'
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  },
  {
    path: '/tab',
    name: 'tab',
    meta: {
      keepAlive: true // 需要被缓存
    },
    component: () => import('../views/Tab.vue')
  },
Vue 3 中的动态 `keep-alive` 组件可以用于缓存动态组件,以提高应用的性能和用户体验。在 Vue 3 中,`keep-alive` 组件已经被重命名为 `Teleport`,但其功能仍然类似。 要在 Vue 3 中使用动态 `keep-alive` 缓存组件,可以按照以下步骤进行操作: 1. 首先,在需要缓存的组件外部包裹一个 `Teleport`(或 `keep-alive`)组件,并设置一个唯一的 `key` 属性。例如: ```vue <template> <Teleport v-bind:key="componentKey"> <component :is="currentComponent"></component> </Teleport> </template> ``` 2. 然后,在你需要切换的组件上,通过修改 `componentKey` 的值来触发组件的重新渲染。例如: ```vue <template> <button @click="toggleComponent">切换组件</button> </template> <script> export default { data() { return { currentComponent: 'ComponentA', componentKey: 0 }; }, methods: { toggleComponent() { this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA'; this.componentKey += 1; } } } </script> ``` 在上面的例子中,每当点击按钮时,`currentComponent` 的值会切换为另一个组件的名称,而 `componentKey` 的值会加 1。这样,`Teleport` 内部的组件会重新渲染,并且之前渲染过的组件会被缓存起来。 请注意,Vue 3 中的 `Teleport` 组件需要配合 Vue全局 `provide/inject` API 使用,以确保组件状态的正确传递。如果你需要更详细的示例或更多关于 Vue 3 动态 `keep-alive` 的信息,可以参考 Vue 3 的官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值