Vue——动态组件、缓存组件keep-alive、异步组件

目录

组件高级

2.动态组件

3.缓存组件keep-alive

4.异步组件 (高薪意向)

方法一:通过webpack2.0的按需加载 (不常用)

方法二:通过webpack2+es2015返回一个promise  (import函数)(主流 ,常用)

方法三:高级异步组件(可以处理加载状态)


组件高级

1、传值     2.动态组件    3.缓存组件keep-alive     4.异步组件(高薪意向)

2.动态组件

有的时候,我们希望页面中的某个地方,在不同组件之间进行动态切换,这时候除了条件渲染,还可以使用动态组件

component 标签的 is属性语法:is后跟组件的变量名决定使用哪个组件来渲染

is是组件名  :is是data中的变量中保存的组件名

<component  is="Sinabox"></component>     ==> <Sinabox/>

Sinabox是一个组件名,字符串,帮我们写代码<Sinabox/>

<component v-bind:is="mycomponent"> </component>

mycomponent就是一个变量了,去下面取

App.vue

<template>
	<div>
		<!-- <button @click="fn(0)">1</button>
		<button @click="fn(1)">2</button>
		<button @click="fn(2)">3</button>
		<Box1 v-if="arr[0]"></Box1>
		<Box2 v-if="arr[1]"></Box2>
		<Box3 v-if="arr[2]"></Box3> -->
		<!-- "Box3"是一个组件名 字符串  帮我们写代码<Box3/> -->
		<!-- <button @click="fn('Box1')">1</button> -->
		<button @click="mytemp='Box1'">1</button>
		<button @click="fn('Box2')">2</button>
		<!-- <button @click="()=>{this.mytemp='Box3'}">3</button> -->
		<button @click="mytemp='Box3'">3</button>
		<component v-bind:is="mytemp"></component>
	</div>
</template>
<script>
	import Box1 from "./Box1.vue"
	import Box2 from "./Box2.vue"
	import Box3 from "./Box3.vue"
	export default {
		data() {
			return {
				arr: [true,false,false],
				mytemp:"Box2"
			}
		},
		components:{
			Box1,
			Box2,
			Box3
		},
		methods:{
			fn(index){
				// console.log(66666)
				// this.arr.fill(false)
				// // console.log(this.arr)
				// this.$set(this.arr,index,true)
				this.mytemp=index
			}
		}
	}
</script>
<style>
</style>

Box1/Box2/Box3.vue

<template>
	<div>
		box1 /Box2/Box3
	</div>
</template>
<script>
	export default {
	}
</script>
<style>
</style>

3.缓存组件keep-alive

动态组件的切换,切换后是不会缓存之前被切换掉的组件的,每次切换新组件的时候,Vue 都创建了一个新的组件对象。
有时候我们希望在A组件时用户做了一些操作,切换B组件时做了一些操作,当切回A组件时希望记住A的操作,不要重新创建A组件,keep-alive可以缓存动态切换的组件


失活的组件将会被缓存!默认全部加载过的组件就会缓存起来
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

 提供有 include  、exclude 、max

(可以写组件名字符串,也可以写正则表达式)

<keep-alive :include="/a|b/"> 
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>


include==> 表示a,b组件被缓存,其他组件不缓存

exclude==>代表除了xx组件其他的组件缓存

max==> 最多可以缓存多少个组件实例,一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉

eg==>  :max=“2”==>代表缓存最近被渲染的2个组件

匹配首先检查组件自身的 name 选项,匿名组件不能被匹配。

keep-alive 提供了钩子函数==>

1、activated ==>在切回来的时候,又再次执行这个函数,就可以在里面做网络请求

==>使用场景: 上面的大分类,点了之后,去选择下面小分类,进行网络请求

2、deactivated==>离开某个组件的时候触发

(在2.2.0及其更高版本中,这两个函数必须用在keep-alive 里面树内的所有嵌套组件中才会触发)

App.vue

<template>
	<div>
		<button @click="mytemp='Box1'">1</button>
		<button @click="fn('Box2')">2</button>
		<button @click="mytemp='Box3'">3</button>
		<keep-alive>
			<component v-bind:is="mytemp"></component>
		</keep-alive>
	</div>
</template>
<script>
	import Box1 from "./Box1.vue"
	import Box2 from "./Box2.vue"
	import Box3 from "./Box3.vue"
	export default {
		data() {
			return {
				arr: [true, false, false],
				mytemp: "Box1"
			}
		},
		components: {
			Box1,
			Box2,
			Box3
		},
		methods: {
			fn(index) {
				this.mytemp = index
			}
		}
	}
</script>
<style>
</style>

Box1.vue

<template>
	<div class="box">
		email:<input type="text" v-model="email">
		pwd:<input type="password" v-model="pwd"> 

	</div>
</template>
<script>
	export default {
		data() {
			return {
				email: "",
				pwd:""
			}
		},
		created() {
			console.log("我创建完成了 而且一辈子只会执行一次这个函数")
		},
		beforeDestroy() {
			console.log("box1:我要销毁了")
		},
		mounted(){
			console.log("根据参数的配置  去请求后端数据")
		},
		activated(){
			console.log("activated--------------------")
		},
		deactivated() {
			console.log("deactivated")
		}
	}
</script>
<style scoped="scoped">
	.box{
		width: 400px;
		height: 400px;
		background-color: aliceblue;
	}
</style>

Box2.vue

<template>
	<div class="box">
		box2
		<input type="text" v-model="msg">
	</div>
</template>
<script>
	export default {
		data() {
			return {
				msg: "123"
			}
		},
	}
</script>
<style scoped="scoped">
	.box{
		width: 400px;
		height: 400px;
		background-color: darkgoldenrod;
	}
</style>

Box3.vue

<template>
	<div class="box">
		box3
		<input type="checkbox" name="test" id="test" v-model="msg"/>
	</div>
</template>
<script>
	export default {
	data() {
		return {
			msg: "helo"
		}
	},	
	}
</script>
<style scoped="scoped">
	.box{
		width: 400px;
		height: 400px;
		background-color: darkorange;
	}
</style>

4.异步组件 (高薪意向)

vue开发过程中,我们会做出特别多特别多的组件,包括login,header,footer,main等等。这样使整个网站看起来就十分的庞大

当我们在打开网页的时候,突然一下子把这些所有的组件加载上来,这么多的请求全部同时开始请求,势必会造成网页打开很慢,使客户得到的是非常差劲的体验。

SPA: single page app

在单页应用中,如果没有用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,延时过长,不利于用户体验

而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时

异步加载并缓存组件:

1、 异步加载组件:用不到的组件不会加载,因此网页打开速度会很快,当你用到这个组件的时候,才会通过异步请求进行加载;

官方解释:**Vue允许将组件定义为一个异步解析(加载)组件定义的工厂函数,即Vue只在实际需要渲染组件时,才会触发调用工厂函数,并且将结果缓存起来,用于将来再次渲染**。

2、 组件缓存起来:通过异步加载的组件会缓存起来,当你下一次再用到这个组件时,丝毫不会有任何的疑迟,组件很快会从缓存中加载出来。

方法一:通过webpack2.0的按需加载 (不常用)

//1 全局:
 Vue.component('component-name',function(resolve){
 //require 语法告诉 webpack自动将编译后的代码分割成不同的块
 //这些块将通过 Ajax 请求自动下载
   require(['./my-async-componnet'],resolve)
 })
 //注册全局组件名,但只有一个名字,没有实体,相当于空的
//当需要这个组件时,调用上面的工厂函数,触发webpack的异步加载模块方法
//然后异步请求一个模块,请求成功后,这个模块内容即为组件实体部分,并对应地方渲染,加载内容也缓存下来。

//2 局部
 new Vue({
   components: {
        'component-name':function(resolve) {
           require(['./my-component'], resolve)
        }
   }
 })
 

方法二:通过webpack2+es2015返回一个promise  (import函数)(主流 ,常用)

//1 全局:
Vue.component('component-name',
 ()=> import('./my-async-componnet')//这个 `import` 函数会返回一个 `Promise` 对象,不要问我为什么,人家webpack这样设计的。
 )
//2 局部:
 new Vue({
   components: {
       'component-name': () =>  import('./my-async-componnet')//这个 `import` 函数会返回一个 `Promise` 对象。
   }
 })

方法三:高级异步组件(可以处理加载状态)

常常用在路由中使用,vue 2.3.0+ 新增终极解决方案,要求路由2.4.0+

//工厂对象可以返回一个如下对象,对象里面的一些配置参数
const AsyncComponent = () => ({
  // 需要加载的组件 (这个 `import` 函数会返回一个 `Promise` 对象。)
  component: import('./MyComponent.vue'),
  // 异步组件加载时使用的组件
  loading: LoadingComponent,
  // 加载失败时使用的组件
  error: ErrorComponent,
  // 展示加载时组件的延时时间。默认值是 200 (毫秒)
  delay: 200,
  // 如果提供了超时时间且组件加载也超时了,
  // 则使用加载失败时使用的组件。默认值是:`Infinity`
  timeout: 3000
})

 App.vue

<template>
	<div>
		<h1>test</h1>
		<button @click="fn">b</button>
		<component :is="n"></component>
		<Box2></Box2>
	</div>
</template>
<script>
	import a from "./a.vue"
	// import b from "./b.vue"
	import LoadingComponent from "./LoadingComponent.vue"
	import ErrorComponent from "./ErrorComponent.vue"
	export default {
		data() {
			return {
				n: "Box1"
			}
		},
		methods: {
			fn() {
				this.n = "Box2"
			}
		},
		components: {
			Box1: a,
			// Box2: function(resolve) {
			// 	require(['./b.vue'], resolve)
			// }
			// Box2:()=>import("./b.vue") //最常用的方式
			Box2: () => ({
				// 需要加载的组件 (这个 `import` 函数会返回一个 `Promise` 对象。)
				component: import('./b.vue'),
				// 异步组件加载时使用的组件
				loading: LoadingComponent,
				// 加载失败时使用的组件
				error: ErrorComponent,
				// 展示加载时组件的延时时间。默认值是 200 (毫秒)
				delay: 200,
				// 如果提供了超时时间且组件加载也超时了,
				// 则使用加载失败时使用的组件。默认值是:`Infinity`
				timeout: 3000
			})
		}
	}
</script>
<style>
</style>

a.vue   /b.vue

<template>
	<div>a</div>
</template>
<script>
	export default {
	}
</script>
<style>
</style>

ErrorComponent.vue

<template>
	<div>
		网络不行 加载失败了 刷新试试
	</div>
</template>
<script>
	export default {
	}
</script>
<style>
</style>

LoadingComponent.vue

<template>
	<div>
		加载中.....
	</div>
</template>
<script>
	export default {
	}
</script>
<style>
</style>
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值