vue 动态组件+全局组件+keepAlive
vue 动态组件+全局组件+keepAlive
故心故心故心故心小故冲啊
文章目录
- vue 动态组件+全局组件+keepAlive
- 动态模板
- 1、通过条件匹配来显示
- 2、动态模板
- 3、异步组件
- 全局组件定义
- 组件缓存 keep-alive
动态模板
当在这些组件之间切换的时候,有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题
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)
- directory: 要查找的文件路径
- useSubdirectories: 是否查找子目录
- 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')
},
还没有评论,来说两句吧...