一、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>
结果显示:同上