一、Vue
1、Vue2.0
下载Vue2.0(源码)第三方包:
在存放的文件夹路径下打开黑窗口或者直接在vscode中运行:输入 npm i vue@2
MVVM:Model-View-ViewModel
一种软件架构设计模式,决定了写代码的思想和层次。
M:Model数据模型(数据层,data里定义)
V:View视图(视图层,html页面)
VM:ViewModel视图模型(控制层,vue.js源码)
// 声明式编程:区分于命令式, 只需要声明数据即可,直接用。
语法一:
const wm = new Vue({
el:"#app", // 挂载到#app 模版上
data:{ // 数据层 Model层
msg:"hello world"
}
})
注意:el和data是固定的,是Vue实例化出来的wm对象的属性。data里面的msg是随便起的名。
语法二:
let json = { // 数据层 Model层
msg: "hello world",
age: 18,
list: ["a", "b", "c", "d", 'e']
}
// json已经 被vm对象所管控,只能在#app这个区域使用数据
const vm = new Vue({
el: "#app", // 挂载到#app 模版上
data: json
})
console.log(json); //
console.log(vm); // 它身上除了有json对象上的属性,还有对应的getter和setter方法
// 想改变json的msg的值,看看改一下vm(通过改变vm代理对象的 msg属性,照样修改了json对象的数据)
vm.msg = 'hello vue';// 走setter,
Vue2.0 底层使用的Object.defineProperty()
ViewModel层如何知道数据变化了,更改到view层上?
1.VM一旦创建,会将data上的数据作为属性挂载到VM实例对象上(可以通过上述代码看出,vm.msg)
2.内部借助于Object.defineProperty(),将data中的属性遍历,并为每一个属性设置getter和setter方法
3.当获取数据时,会调用getter方法;设置数据时,会调用setter方法。
4.设置数据的时候,触发setter方法,setter方法内部会自动触发watcher方法,进行新旧DOM对比,更新渲染到DOM上
2、Vue3.0
下载Vue3.0(源码)第三方包:
在存放的文件夹路径下打开黑窗口或者直接在vscode中运行:输入 npm i vue
<div id="app">
{{age}}
{{name}}
<!-- {{docublueAge}} -->
<button @click="addOne">点我加1</button>
<button @click="add$">点我加!</button>
</div>
<script src="./lib/vue.global.js"></script>
<script>
1.选项式api(Vue2.0中也支持):
1)从Vue中结构出createApp
let{createApp}=Vue
2)createApp()创建应用的,参数是配置项
let app=createApp({
//data选项
data(){
return {
age:18
}
},
//methods
methods:{
addOne(){
this.age++
}
},
//computed
computed:{
docublueAge(){
return this.age*2
}
}
})
3)将应用挂载到#app这个区域的视图层
app.mount('#app')
2. 组合式api 入口是setup(){}
let{ref}=Vue
Vue.createApp({
setup(){
//操作age变量
let age=ref(18)
let addOne=function(){
age.value++
}
//操作name变量
let name=ref('张三')
let add$=function(){
name.value+='!'
}
return {
age,addOne,name,add$
}
}
}).mount('#app')
</script>
3、选项式api和组合式api
api:application programming interface
Vue2.0 api:选项式api,没有组合式api
Vue3.0 api:选项式api(大多数和Vue2.0选项式api一样,有一些不一样),又有组合式api
4、模板语法
声明式语法不支持undefined和null声明式的渲染到页面,其他都支持。
1.文本插值{{}}
2.{{}}内可以书写表达式(可以计算出一个结果的式子)
3.{{}}内支持哪些类型的变量
<div id="app" v-cloak>
{{msg}} <br>
{{num}} <br>
{{flag}} <br>
{{arr}} <br>
{{obj}} <br>
{{unde}} <br>
{{nu}} <br>
{{num*2}} <br>
{{flag?"true":"false"}} <br>
{{num+100}} <br>
{{msg.split("").reverse().join("")}}
</div>
<script src="./lib/vue.global.js"></script>
<script>
Vue.createApp({
data(){
return {
msg:'hello'
num: 10,
flag: true,
arr: [12, 45, 56],
obj: { name: 'zs', age: 18 },
unde: undefined,//不显示
nu: null//不显示
}
}
}).mount('#app')
</script>
5、文本类指令
v-html='data中的变量' 写在标签上作为属性(可以识别标签)
v-text='data中的变量' 写在标签上作为属性
常量:字符串常量('字符串');数字常量(数字);布尔常量(true/false)
v-html = '常量' 写在标签上作为属性(可以识别标签)
v-text = '常量' 写在标签上作为属性
注意:
Vue2.0中使用v-html和v-text会覆盖标签直接的内容(标签内的内容会忽略)
Vue3.0中使用v-html和v-text,并且标签内有内容,会给你一个提示
6、属性绑定
语法:
v-bind:属性名='data中的变量'
v-bind:属性名='常量'
简写:
:属性名='data中的变量'
7、事件绑定
语法:
v-on:事件名='少量的js代码(要求代码是赋值语法)'
v-on:事件名='函数名'
v-on:事件名='函数名(参数)'
简写:
@事件名='少量的js代码(要求代码是赋值语法)'
@事件名='函数名'
@事件名='函数名(参数)'
事件对象如何获取:
1.调用时不传参数时,默认就在第一个形参位置就是事件对象。
2.调用时传递参数时,需要手动的把事件对象$event放在最后一个参数位置。
事件修饰符:
@事件名.prevent='事件处理函数'
@事件名.stop='事件处理函数'
@事件名.prevent.stop='事件处理函数'
@事件名.prevent
特殊事件:如keyup事件
按键修改符:
@keyup.enter='事件处理函数'(键盘按键抬起时并按下了回车键,就会指向事件处理函数)
.enter
.delete(捕获'delete'和'Backspace'两个按键)
.space(空格键)
.up(上箭头)
.down(下箭头)
.left(左箭头)
.right(右箭头)
配合功能键:
.ctrl键
.alt键
.shift键
.meta键
按下enter键的同时按下ctrl键
@keyup.ctrl.enter=''
eg:
<style>
.red {
color: red;
}
.father {
width: 300px;
height: 300px;
background-color: palegreen;
}
.son {
display: block;
width: 100px;
height: 100px;
background-color: paleturquoise;
}
</style>
<div id="app">
<input type="text" @keyup.enter.ctrl="enterFn">
<!-- <a href="http://www.baidu.com" @click.prevent="alertBd">百度</a> <br> -->
<!-- <a href="http://www.baidu.com" @click.prevent="alertBd1(5,$event)">百度</a> -->
<div class="father" @click="fatherFn">
<a class="son" @click.prevent.stop="sonFn" href="http://www.baidu.com">哈哈哈</a>
</div>
<!-- 这种写法也支持:意思是阻止默认行为,但是没有阻止冒泡 -->
<div class="father" @click="fatherFn">
<a class="son" @click.prevent href="http://www.baidu.com">哈哈哈</a>
</div>
</div>
<script src="./lib/vue.global.js"></script>
<script>
Vue.createApp({
data() {
return {
age: 18,
flag: true
}
},
methods: {
addAge() {
this.age += 5;// 访问属性的时候,要使用this.age访问 (age现在挂载在app应用上的)
},
addAgeFive(num) {
this.age += num
},
alertBd(e) { // 形参的第一个位置
alert("百度");
},
alertBd1(num, e) {
alert("百度");
},
sonFn() {
alert("son")
},
fatherFn() {
alert("father")
},
enterFn() {
alert("我抬起并按下了回车键")
}
}
}).mount("#app")
</script>
8、条件渲染
v-if 作用:用来控制标签的显示和隐藏。
v-if 原理:使用js中创建(document.createElement())和删除(ele.remove())
v-show 作用:用于控制标签的显示和隐藏。
v-show 原理:使用js中display:none和display:block来控制的
v-if和v-show的区别:
原理:
v-if 利用标签的创建和删除
v-show 利用标签的display显示和隐藏
性能:
v-if 每一次切换都会消耗性能
v-show 初始显示,只消耗一次性能
使用时:
v-if 不频繁使用显示和隐藏时
v-show 频繁使用显示和隐藏时
安全性:
v-if 安全性能更好
v-show 安全性不好
使用template标签:
v-if 可以用在template标签上
v-show 不可以用在template标签上
eg:
<div id="app">
<button @click="age++">点我变大</button> {{age}}
<!-- <p v-if="age<18">未成年</p>
<p v-else>成年</p> -->
<!--<p v-show="age<18">未成年</p>
<p v-show="age>=18">成年</p> -->
<!-- 它是一个标签,但是不会显示到页面 -->
<template v-if="age<18">
成年人的世界,你懂得~
</template>
</div>
<script src="./lib/vue.global.js"></script>
<script>
Vue.createApp({
data () {
return {
age:16
}
},
methods: {
},
}).mount("#app")
</script>
9、循环
口诀:想让谁出现多次,就把v-for写在谁身上
语法一:
遍历数字:
v-for='item in 数字' :key='唯一的,有id使用id,没有id使用index'
语法二:
遍历数组:
v-for='(item,index) in data中的数组' :key='唯一的,有id使用id,没有id使用index'
语法三:
遍历对象:
v-for='(value,key,index) in data中的对象' :key='唯一的,有id使用id,没有id使用index'
eg:
<div id="app">
<!-- 口诀:想让谁出现多次,就把v-for写在谁身上 -->
<!-- 语法一: 遍历数字 -->
<span v-for="(item,index) in 10" :key="index">{{item}} ====={{index}}<br></span>
<!-- 遍历数组 -->
<ul>
<li v-for="(item,index) in arr" :key="index">{{item}}</li>
</ul>
<ul>
<li v-for="(item,index) in list" :key="item.id">{{item.produt}}</li>
</ul>
<span v-for="(item,key) in obj" :key="key">{{item}} ---{{key}}</span>
</div>
<script src="./lib/vue.global.js"></script>
<script>
Vue.createApp({
data() {
return {
str: "helloworld",
arr: ["apple", "peach", "pear", "banana", "watermelon"],
list: [
{ id: 1, produt: "手机1" },
{ id: 2, produt: "手机2" },
{ id: 3, produt: "手机3" },
{ id: 4, produt: "手机4" },
],
obj: {
name: "zs",
age: 18,
sex: "男"
}
}
},
methods: {
},
}).mount("#app")
</script>
10、v-if和v-for的优先级
Vue2.0中审查元素:v-for的优先级高于v-if
Vue3.0中审查元素:v-if的优先级高于v-for
注意:v-if和v-for尽量不要写在一个标签上;v-show和v-for可以写在一个标签上。
11、购物车案例
<div id="app">
<table border="1px">
<thead>
<tr>
<td>商品名称</td>
<td>商品单价</td>
<td>商品数量</td>
<td>商品小计</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in list" :key="item.id">
<td>{{item.product}}</td>
<td>{{item.price}}</td>
<td>
<button>-</button>
<input type="text" :value="item.num" size="2">
<button @click="addNum(item.id)">+</button>
</td>
<td>
{{item.price*item.num}}
</td>
<td>
<button @click="delNum(item.id)">x</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<!-- 模板语法可以写表达式:只要计算出一个结果就可以 -->
{{list.reduce((sum,item)=>sum+=item.price*item.num,0)}}
</td>
</tr>
</tfoot>
</table>
</div>
<script src="./lib/vue.global.js"></script>
<script>
Vue.createApp({
data() {
return {
list: [
{ id: 1, product: "小米手机", price: 10, num: 1 },
{ id: 2, product: "华为手机", price: 60, num: 1 },
{ id: 3, product: "红米手机", price: 30, num: 1 },
{ id: 4, product: "锤子手机", price: 30, num: 1 },
{ id: 5, product: "小灵通手机", price: 10, num: 1 },
]
}
},
methods: {
addNum(id) {
// id: 代表的是具体的哪一个商品 点击的具体的商品
// 找到商品
let goods = this.list.find(item => item.id == id); // 找到的是list的那一个对象
goods.num++;// 对象的num属性
// list会自动变化
},
delNum(id) {
// 过滤: filter会改变原数组吗,不会
let newList = this.list.filter(item => item.id != id);// 过滤出你没有点击删除的所有项
this.list = newList; // 把list重新覆盖啦
}
},
}).mount("#app")
</script>
12、表单输入绑定(v-model)
eg:
v-model的底层原理:
<div id="app">
<!-- <input type="text" v-model="msg"> -->
<!-- 实现一个v-model -->
<!-- 1. 先实现 model到view层 -->
<!-- <input type="text" v-bind:value="msg"> -->
<!-- 2. 将view层同步到model层 -->
<input type="text" v-bind:value="msg" @input="fn">
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: "hello world"
},
methods: {
fn(e){
this.msg = e.target.value; // 将输入的内容赋值给msg变量
}
},
})
</script>
12.1、v-model的作用于复选框
v-model='data中变量的值'
data中变量的值的类型分两大类:
1)data变量的值的类型是数组:v-model关联的值是 以数组形式包含所有选中状态的复选框的value的值。
2)data变量的值的类型是非数组:v-model关联的值是 布尔类型的值(使用频率最高)。
eg:
v-model对于复选框关联的值:
1)v-model的值是'数组'形式:复选框的value值,以数组的形式返回。
2)v-model的值是'非数组'形式:复选框的选中状态。
<div id="app">
<input type="checkbox" v-model="abc" value="篮球">篮球 <br>
<input type="checkbox" v-model="abc" value="足球">足球 <br>
<input type="checkbox" v-model="abc" value="排球"> 排球<br>
<input type="checkbox" v-model="abc" value="铅球">铅球 <br>
{{abc}}
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
abc: ''
// abc: [], /* 写的比较少 */
}
})
</script>
12.2、v-model的作用于下拉列表
eg:
v-model对于下拉列表关联的值:
关联的是下拉列表option的值。
<div id="app">
<select v-model="str">
<option value="上海">上海</option>
<option value="北京">北京</option>
</select>
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
str: "上海"
}
})
</script>
12.3、v-model的作用于输入框和文本域
v-model对于文本域和输入框关联的值是一样的;都是输入的值。
13、选项卡案例
代码思路:
1. 默认显示的哪一项 需要使用索引值就可以完成,v-for在遍历的同时在创建标签,只有满足 index==item.id才拥有这个类名 只有第二个按钮会高亮。
2. 点击的元素的id 赋值给index,index导致:class=”“位置进行了重新判断。
<style>
.btnActive {
background-color: orange;
}
#app .divActive {
display: block;
}
#app div {
display: none;
border: 1px solid grey;
width: 300px;
}
</style>
<div id="app">
<button v-for="(item) in list" :key="item.id" :class="{'btnActive':index==item.id}"
@click="changeIndex(item.id)">{{item.title}}</button>
<div v-for="(item) in list" :key="item.id" :class="{'divActive':index==item.id}">
{{item.content}}
</div>
</div>
<script src="./lib/vue.global.js"></script>
<script>
let app = Vue.createApp({
data() {
return {
index: 1,
list: [
{ id: 0, title: "教育", content: "教育的内容" },
{ id: 1, title: "娱乐", content: "娱乐的内容" },
{ id: 2, title: "体育", content: "体育的内容" },
]
}
},
methods: {
changeIndex(id) {
// id: 具体点击的元素的id
this.index = id;
}
},
})
app.mount("#app")
</script>
14、样式绑定
class绑定:
1)基本绑定样式:
<p class="active"> 白日依山尽 </p>
<p :class="'active'"> 白日依山尽 </p>
<p :class="x"> 白日依山尽 </p>
<p :class="flag?x:''"> 白日依山尽 </p>
2)对象的方式:
<p :class="{'active':false,'border':true}"> 黄河入海流 </p>
3)数组的方式:
<p :class="['active','border']"> 欲穷千里目 </p>
<p :class="[x,y]"> 欲穷千里目 </p>
style绑定:
1)对象的形式:
<p :style="{backgroundColor:'red',fontSize:'28px'}"> 更上一层楼 </p>
<p :style="{backgroundColor:z}"> 更上一层楼 </p>
<script src="./lib/vue.global.js"></script>
<script>
let app = Vue.createApp({
data() {
return {
flag: true,
x: 'active',
y: 'border',
z: "orange"
}
},
})
app.mount("#app")
</script>
15、计算属性
1.什么是计算属性?为什么使用计算属性?
模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。
2.什么时候使用?
依赖其他属性计算而来的属性,可以写到computed选项中,写起来像方法,使用起来是属性。
3.计算属性和方法的区别?
1)使用的时候,方法需要带(),计算属性不需要带(),依赖项发生不发生,调用一次,重新执行一次方法体。
2)计算属性值会基于其响应式依赖被缓存。当依赖项不发生,直接从缓存中取,当依赖项发生变化,会重新调用一次。
计算属性:
1)
computed: {
计算属性的名字:function(){
return ;
}
}
上述写法存在的问题:只能读,不能写。
2)计算属性变成 可读可写:
computed: {
计算属性的名字: {
// 获取的语法
get() {
return;
},
set(val){
}
}
}
15.1、计算属性案例
<div id="app">
<input type="checkbox" v-model="isAll"> 全选
<hr>
<p v-for="item in list" :key="item.id">
<input type="checkbox" v-model="item.isCheck">
{{item.product}}
</p>
</div>
<script src="./lib/vue.global.js"></script>
<script>
/*
下面属性中,哪个可以写成计算属性, 写成了计算属性,它会不会改变呢?
什么时间使用计算属性,当一个属性的值依赖于其他的属性计算而来的时候,
isAll需要依赖list中所有的isCheck计算而来
1. isCheck全部为true,isAll就是true,isCheck有一个是false,isAll就是false
2. 当更改isAll的值的时候,说明有修改计算属性的需求,所以需要使用带getter和setter的方法
*/
let app = Vue.createApp({
data() {
return {
list: [
{ id: 1, product: "小米手机", isCheck: false },
{ id: 2, product: "华为手机", isCheck: true },
{ id: 3, product: "红米手机", isCheck: true },
{ id: 4, product: "锤子手机", isCheck: true },
{ id: 5, product: "小灵通手机", isCheck: true },
]
}
},
computed: {
// 这种语法只能读,不能更改,(只能去改一下list的isCheck,去查看isAll的效果)
// isAll:function(){
// return this.list.every(item=>item.isCheck==true)
// }
// 这种语法 : 可以读可以写
isAll: {
get() {
return this.list.every(item => item.isCheck == true)
},
set(val) {
console.log(val);
this.list.forEach(item => {
item.isCheck = val; // 把当前修改的状态 赋值给下面每一个的isCheck
})
}
}
}
})
app.mount("#app")
</script>
16、侦听器
侦听器:
侦听data中数据的变化。
写法一:
侦听的是基本数据属性:
watch:{
"哪个data":function(newval,oldval){}
}
写法二:
侦听对象:
watch:{
"侦听哪个对象":{
deep:true,-------必须写,深度侦听
immediate:true,-------打开页面就侦听
handler(newval){
newval: 改变后的对象的值,对象中所有的属性都在newval包含
}
}
}
注意:
1)watch 默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。
2)我们可以用一个对象来声明侦听器,这个对象有 handler 方法和 immediate: true 选项,这样便能强制回调函数立即执行.
eg:
<div id="app">
<input type="text" v-model="user.firstName"> +
<input type="text" v-model="user.lastName"> = {{ user.fullName }}
</div>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
user: {
firstName: '张',
lastName: '三',
fullName: ''
}
}
},
watch: {
// 写法是可以的,易懂,但是写起来层次比较多就比较麻烦啦
// 'user.firstName': function (newval, oldval) {
// this.user.fullName = newval + this.user.lastName;// 全名 = 新的值 +lastName
// },
// 'user.lastName': function (newval, oldval) {
// this.user.fullName = this.user.firstName + newval; //
// }
// 侦听的直接是一个user对象,newval就是最新的user对象
user: {
deep: true, // 在侦听对象时必须带上 deep:true
immediate: true, // 打开页面就立即的侦听
handler(newval, oldval) {
// console.log(newval); // 变化后的新的对象,包含着你的firstName和你的lastName,两个任何一个发生变化,user就会变化
this.user.fullName = newval.firstName + newval.lastName;
}
}
},
})
app.mount('#app')
</script>
16.1、手动开启侦听
this.$watch("data属性",()=>{}) 返回一个一个方法,调用这个方法进行结束侦听
eg:
<div id="app">
{{count}}
<button @click="count++">count+1</button>
<button @click="startWatch">开始监听</button>
<button @click="endWatch">结束监听</button>
</div>
<script src="./lib/vue.global.js"></script>
<script>
let app = Vue.createApp({
data() {
return {
count: 1
}
},
methods: {
startWatch() {
this.end = this.$watch("count", (newval) => {
console.log(newval);
})
},
endWatch() {
this.end()
}
},
})
app.mount("#app")
</script>
17、vue中的响应式系统
30、组件通信
1.父组件向子组件传值:
父组件需要在子组件身上通过自定义属性传值,子组件内部通过props接收。
2.子组件向父组件传值:
父组件需要在子组件身上绑定自定义事件,子组件内部通过$emit(触发的事件,需要传的值)。
3.兄弟组件传值:(只用于Vue2.0中)
1)先实例一个公共的通信对象(一般js文件)。
import { createApp } from 'vue'
//实例化通信对象 并导出
export default createApp()
2)并且在两个兄弟组件引入这个通信对象。
import eventBus from '../utils/eventBus'
3)在接受值的组件中通过$on监听事件。
mounted() {
// 监听事件
// Vue 3 中 没有$on方法, 会报错
eventBus.$on('tranferdata', (data) => {
console.log('接收到的数据:', data);
})
}
4)在发送值的组件中通过$emit去触发事并传值。
methods:{
handleClick(){
// Vue 3 中 没有$emit方法, 会报错
eventBus.$emit('tranferdata',88888);
}
}
4.跨组件传值:
外层组件通过provide选项传值,内层组件通过inject接受值。(注意:外层组件的里面每一层组件都可以收到传过去的值,哪个组件想接受就添加inject选项,但接受到值后不能修改值)
provide: {
money: 88888,
arr: [1, 2, 3]
}
inject:['money']
inject:['money','arr']
5.v-model用在自定义组件上,实现对子组件内容的双向绑定:
1)在自定义组件上使用v-model。
<MyInput v-model="phone" />
2)在子组件的操作如下:
Vue3.0中:里面的'modelValue'、'update:modelValue'、:value="modelValue"中的'modelValue'都是固定的。
<input type="text" placeholder="输入手机号" :value="modelValue" @input="handleInput">
export default {
props: ['modelValue'],//声明通过哪个属性接收传来的值
emits: ['update:modelValue'],//声明事件, 将来可以通过触发该事件来更新父组件中v-model对应属性的值.
// mounted(){
// this.$emit('update:modelValue',this);
// },
methods: {
handleInput(e) {
this.$emit('update:modelValue', e.target.value)
}
}
}
Vue2.0中:里面的'abc'、'update:abc'、:value="abc"中的abc不是固定的。
<input type="text" placeholder="输入手机号" :value="abc" @input="handleInput">
export default {
props: ['abc'],//声明通过哪个属性接收传来的值
emits: ['update:abc'],//声明事件, 将来可以通过触发该事件来更新父组件中v-model对应属性的值.
methods:{
handleInput(e){
this.$emit('update:abc',e.target.value)
}
}
}
31、ref参数
ref放置在'标签'上:获取的是所在标签的dom节点。
ref放置在'组件'上:获取的是所在组件的实例,进而可以获取子组件上的属性和方法。
32、插槽
1.作用:自定义组件内容。
2.分类:
1)默认插槽 <slot />
2)具名插槽 <slot />
3.如何使用:
1)在自定义组件中写内容。
2)在子组件中接受的位置处写<slot />。
注意:
1)自定义组件不能再用单标签了<Dialog />;必须使用双标签<Dialog></Dialog>了。
2)<slot />标签也有name属性,代表标签的名字;可进行布置精准插槽。v-slot:title写在父组件上,<slot name="title" />写在子组件上。如下:
eg:
父组件
<Dialog>
<template v-slot:title>
警告
</template>
<template v-slot:text>
你的svip还有3天过期!
</template>
</Dialog>
子组件:
<div class="dialog" v-show="isvisible" @click="hide">
<div class="content" @click.stop="">
<!-- <slot /> 这是默认插槽 -->
<!-- <slot name="" /> 这是具名插槽 -->
<div class="title"> <slot name="title" /> </div>
<div class="text"> <slot name="text" /> </div>
<div class="btns">
<span @click="hide">取消</span>
<span @click="hide">确定</span>
</div>
</div>
</div>
33、内置组件
1.动态组件:component;缓存组件:keep-alive
2.如何使用:
keep-alive 缓存组件,需要包裹在需要缓存的组件外部, 被缓存的组件会保留在计算机内存中, 组件在下一次切换时只需要从内存中读取并显示出来即可。
keep-alive标签上有2个属性:
1)include 指定需要缓存的组件列表。
2)exclude 指定不需要缓存的组件列表。
<keep-alive include="ChildA,ChildB" exclude="ChildC">
<component :is="coms[index]" />
</keep-alive>
3.与两个生命周期配合使用:activated------激活状态;deactivated------缓存状态。
activated() {
console.log('A组件激活了');
},
deactivated() {
console.log('A组件缓存了');
},