vue——组件高级之动态组件、缓存组件、异步组件

 一、v-if 切换组件

  父组件App.vue:

<template>
	<div>
		<button @click="fn(0)">box1显示</button>
		<button @click="fn(1)">box2显示</button>
		<button @click="fn(2)">box3显示</button>
		<Box1 v-if="arr[0]"></Box1>
		<Box2 v-if="arr[1]"></Box2>
		<Box3 v-if="arr[2]"></Box3>
	</div>
</template>
<script>
import Box1 from "./Box1.vue";
import Box2 from "./Box2.vue";
import Box3 from "./Box3.vue";
export default {
  data() {
    return {
		arr:[false,false,false]
	};
  },
  methods: {
    fn(index) {
		this.arr.fill(false)
		console.log("点击了box"+(index+1))
		this.$set(this.arr,index,true)
	}
  },
  components: {
    Box1,
    Box2,
    Box3
  }
};
</script>

  子组件 Box1.vue   Box2.veu  Box3.vue文件 类似:

<template>
	<div>
		box1
	</div>
</template>

<script>
	export default {}
</script>

 结果显示:

二、动态组件:

component 标签的 is属性

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

两种写法:

  • <component is="selectedbox"></component>   代表==><selectedbox/>
  • <component v-bind:is="mycomponent"></component>

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

  父组件App.vue:

<template>
	<div>
		<button @click="fn('Box1')">box1显示</button>
		<button @click="fn('Box2')">box2显示</button>
		<button @click="fn('Box3')">box3显示</button>
		<component :is="mycomponent"></component>
	</div>
</template>
<script>
import Box1 from "./Box1.vue";
import Box2 from "./Box2.vue";
import Box3 from "./Box3.vue";
export default {
  data() {
    return {
		mycomponent:""
	};
  },
  methods: {
    fn(component) {
		this.mycomponent=component
        console.log("点击了"+component)
	}
  },
  components: {
    Box1,
    Box2,
    Box3
  }
};
</script>

  子组件 Box1.vue   Box2.veu  Box3.vue文件 类似:

<template>
	<div>
		box1
	</div>
</template>

<script>
	export default {}
</script>

  结果显示: 

 三、缓存组件keep-alive :

  • 动态组件切换时,会把切换前的组件销毁了 只留下当前组件,每次切换新组件的时候,Vue 都创建了一个新的组件对象。
  • 有时候我们希望在A组件时用户做了一些操作,切换B组件时做了一些操作,当切回A组件时希望记住A的操作,不要重新创建A组件就引入缓存组件 。
  • keep-alive可以缓存动态切换的组件

   keep-alive提供的属性

  • include 设置需要缓存的组件 (组件名/正则) <keep-alive include="Box1">
  • exinclude 设置不需要缓存的组件 (组件名/正则)
  • :max 缓存最近切换的几个组件

   keep-alive提供的钩子函数

      必须在keep-alive里使用:activated  deactivated

  • activated:页面第一次进入的时候,钩子触发的顺序是 created->mounted->activated
  • deactivated: 页面退出的时候会触发 deactivated,当再次前进或者后退的时候只触发 activated

   父组件App.vue:

<template>
	<div>
		<button @click="fn('Box1')">box1显示</button>
		<button @click="fn('Box2')">box2显示</button>
		<button @click="fn('Box3')">box3显示</button>
		<keep-alive>
		  <component :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 {
      mytemp: ""
    };
  },
  methods: {
    fn(component) {
      this.mytemp = component;
      console.log("点击了" + component);
    }
  },
  components: {
    Box1,
    Box2,
    Box3
  }
};
</script>

   子组件 Box1.vue :

<template>
	<div>
		<p>box1</p>
		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("创建完成后 只执行一次")
		},
		activated(){
			console.log("进入页面啦")
		},
		deactivated() {
			console.log("退出页面啦")
		}

	}
</script>

   子组件 Box2.vue :

<template>
	<div class="box">
	<p>box2</p>	
		<input type="text" v-model="msg">
	</div>
</template>

<script>
export default {
  data() {
    return {
      msg: "12345"
    };
  }
};
</script>

  结果显示: 

四、异步组件:

懒加载思想:使用组件的时候才会加载组件

当网站很大时就会有很多的组件,包括login,header,footer,main等等,所以打开网页的时候,突然一下子加载所有的组件时会有很多的请求同时开启,势必会造成网页加载太慢。客户体验感不好。所以要运用懒加载可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时间。

建议:首屏要使用的组件在开头引入  其他组件在声明处import引入

异步加载并缓存组件:

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

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

2、 组件缓存:通过异步加载的组件会缓存起来,当下一次再用到这个组件时,组件会直接从缓存中加载出来。

(1)通过webpack2.0的按需加载--require

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

  App父组件:

<template>
	<div>
		<h1>App组件</h1>
		<button @click="fn">切换到Box2组件</button>
		<component :is="n"></component>
	</div>
</template>

<script>
	import Box1 from "./Box1.vue"
	export default {
		data() {
			return {
				n: "Box1"
			}
		},
		methods: {
			fn() {
				this.n = "Box2"
			}
		},
		components: {
			Box1,
			Box2: function(resolve) {
				require(['./Box2.vue'], resolve)
			}
		}
	}
</script>

   子组件Box1.vue Box2.vue 组件类似:

//Box1.vue
<template>
	<div>
	<p>box1</p>
	</div>
</template>
//Box2.vue
<template>
	<div>
	<p>box2</p>
	</div>
</template>

结果显示:

 (2)通过webpack2+es2015返回一个promise(主流 )--import

    App父组件:

<template>
	<div>
		<h1>App组件</h1>
		<button @click="fn">切换到Box2组件</button>
		<component :is="n"></component>
	</div>
</template>

<script>
	import Box1 from "./Box1.vue"
	export default {
		data() {
			return {
				n: "Box1"
			}
		},
		methods: {
			fn() {
				this.n = "Box2"
			}
		},
		components: {
			Box1,
            //要切换的时候才调函数引入组件
			Box2:()=>import("./Box2.vue") //最常用的方式
			}
		}
	}
</script>

  子组件Box1.vue Box2.vue 组件类似:

//Box1.vue
<template>
	<div>
	<p>box1</p>
	</div>
</template>
//Box2.vue
<template>
	<div>
	<p>box2</p>
	</div>
</template>

 结果显示:同上

(3)高级异步组件(可以处理加载状态)

 App父组件:

<template>
	<div>
		<h1>App组件</h1>
		<button @click="fn">切换到Box2组件</button>
		<component :is="n"></component>
	</div>
</template>

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

  子组件Box1.vue Box2.vue 组件类似:

//Box1.vue
<template>
	<div>
	<p>box1</p>
	</div>
</template>
//Box2.vue
<template>
	<div>
	<p>box2</p>
	</div>
</template>

  占位组件: LoadingComponent.vue    ErrorComponent.vue

//  ErrorComponent.vue
<template>
	<div>
		网络不行 加载失败了 刷新一下
	</div>
</template>
//  LoadingComponent.vue    
<template>
	<div>
		加载中.....
	</div>
</template>

 结果显示:同上

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈ha~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值