Vue3学习笔记-04
一、监视属性-watch
<div>
<h2>
今天的天气很{{info}}
</h2>
<button @cilck="changeWeather">切换天气</button>
</div>
<script>
new Vue({
el:'root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
}
methods:{
changeWeather(){
this.isHot = !this.isHot
}
}
})
</script>
1.监听isHot是否发生变化-watch
<div>
<h2>
今天的天气很{{info}}
</h2>
<button @cilck="changeWeather">切换天气</button>
</div>
<script>
var vm = new Vue({
el:'root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
}
methods:{
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot:{
//还有很多配置项:例如深度监听等
immediate:true,//表示立即执行的意思,也就是在初始化的时候调用一下handler函数
//当isHot变化的时候,handler被调用
handler(newValue,oldValue){
console.log('isHot被修改了'+'新的值:'+newValue+' 旧的值: '+oldValue)
}
}
}
})
/**
* 还可以使用一下方法进行监听:
* vm.$watch('isHot',{
* //还有很多配置项:例如深度监听等
* immediate:true,//表示立即执行的意思
* //当isHot变化的时候,handler被调用
* handler(newValue,oldValue){
* console.log('isHot被修改了'+'新的值:'+newValue+' 旧的值: '+oldValue)
* })
*/
</script>
2.深度监视
<div>
<h2>
深度监视案例:
</h2>
a的值为{{number.a}}
<button @click="number.a++">a+1</button>
</div>
<script>
new Vue({
el:'#root',
data:{
isHot:true,
number:{
a:1,
b:1
}
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
watch:{
//deep监视多级结构中某个属性的变化
number:{
deep:true,//深度监听已经打开了
handler(){
console.log('a变化了')
}
}
}
})
</script>
重点:
深度监视:
1.Vue中的watch默认不监测对象内部值的变化(只监听到一层);
2.配置deep:true可以监测对象内部值的变化(多层);
备注:
1.Vue自身可以监测对象内部值的改变,但是Vue提供的watch默认不认识;
2.使用watch时,根据数据的具体结构,决定是否采用深度监视。
3.深度监视的简写
如果需要配置deep 、 immediate 的时候,就不能简写
当配置项只有handler的时候,就可以简写:
watch:{
isHot(newValue,oldValue){
console.log('isHot被修改了')
}
}
4.computed和watch之间的区别
1.computed能完成的功能,watch也能够完成
2.watch能够完成的功能,computed不一定能够完成,例如:watch可以进行异步操作。
两个重要的小原则:
1.所被Vue管理的函数,最好都写成普通函数,这样的this的指向才是vm(Vue的一个实例) 或者组件实例对象;
2.所有不被Vue所管理的函数(定时器函数、ajax的回调函数等),最好都写成箭头函数,这样的this的指向才是vm 或 组件实例对象。
二、样式的绑定
1.class的绑定
点击按钮,其div的样式发生改变
只用于:当样式的类名不确定的时候,需要动态的指定
<div id="root">
<div class="basic":class="mood" id="demo" @click="changeMood">{{name}}</div>
</div>
<script>
new Vue({
el:'root',
data:{
name:'明月二十四月桥',
mood:''
},
methods:{
changeMood(){
this.mood = 'happy'
}
}
})
</script>
有三种写法:
1.字符创写法:使用于样式的类名不确定,需要动态指定
2.数组写法:适用于要绑定的样式个数不确定、名字也不确定
3.对象写法:适用于要绑定的样式的个数确定,名字也确定,但是要动态决定用不用
<div id="root">
<!--字符创写法:使用于样式的类名不确定,需要动态指定-->
<div class="basic":class="mood" id="demo" @click="changeMood">{{name}}</div><br><br>
<!--要绑定的样式的个数不确定,名字也不确定-->
<div class="basic":class="arr">{{name}}</div><br><br>
<!-- 对象写法,样式在ppp2和ppp3之间的进行切换,使用情况如下:用ppp1不用ppp3; 用ppp3不用ppp1;
都不用
-->
<div class="basic":class="classObj">{{name}}</div>
</div>
<script>
new Vue({
el:'#root',
data:{
name:'明月二十四月桥',
mood:'normal',
arr:['ppp1','ppp2','ppp3'],
classObj:{
ppp1:false,
ppp3:false,
}
},
methods:{
changeMood(){
const arr = ['happy','sad','normal']
const i = Math.floor(Math.random()*3)
this.mood = arr[i]
}
}
})
</script>
2.style的绑定
<div id="root">
<div class="basic" style="font-size:40px;"></div>
<div class="basic" :style="font-size: fsize+'px'"></div>
<div class="basic" :style="styleObj"></div>
</div>
<script>
new Vue({
el:'#root',
data:{
name:'明月二十四月桥',
fsize:40,
styleObj:{
fontSize:fsize+'px',
color:'red',
backgroundColor:'yellow'
}
},
methods:{
}
})
</script>
三、条件渲染
3.1 v-show和v-if的使用
1.使用v-show 做条件渲染:如果取值为false的话,其代码结构还存在
2.使用v-if 做条件渲染:如果取值为false的话,其代码结构不存在(v-if 、v-else-if 、v-else)
当变换频率高的时候,建议使用v-show
<div id="root">
<!--使用v-show 做条件渲染-->
<h2 v-show="a"> 欢迎你!{{name}}</h2>
<!--使用v-if 做条件渲染-->
<h2 v-if="a"> 欢迎你!{{name}}</h2>
<h2>当前的n的值为:{{n}}</h2>
<button @click="n++">点击n+1</button>
<div v-if="n === 1">Angular</div>
<div v-else-if="n === 2">React</div>
<div v-else-if="n === 3">Vue</div>
<div v-else>哈哈</div>
</div>
<script>
new Vue({
el:'#root',
data:{
name:'小jiang同学',
a:true,
n:0
}
})
</script>
3.2 template
母版的意思,最大的一个特点就是不影响结构,在渲染页面的时候,template
就不会存在
注意:template
只能配合 v-if 使用,不能配合v-show来使用
<h2 v-if="n === 1">瓮安</h2>
<h2 v-if="n === 1">你好啊</h2>
<h2 v-if="n === 1">你怎么样</h2>
<!--上述代码重复多个v-if,下面对他进行优化-->
<div v-if="n === 1">
<h2 >瓮安</h2>
<h2>你好啊</h2>
<h2>你怎么样</h2>
</div>
<!--上面第二种加div的方式,影响了原来的代码结构,在下面继续优化-->
<template v-if="n === 1">
<h2 >瓮安</h2>
<h2>你好啊</h2>
<h2>你怎么样</h2>
</template>
四、列表渲染
4.1基本渲染
1.遍历数组
2.遍历对象
3.遍历字符串
4.遍历指定次数
<!--遍历数组-->
<h2>人员信息</h2>
<ul>
<li v-for="item in persons" :key="item.userId">{{item.userId}}-{{item.name}}-{{item.age}}</li>
</ul>
<br>
<br>
<h2>人员信息</h2>
<ul>
<!--这里的item接收的是persons中的对象值,i是对应的索引值,就相当于是数组的下标-->
<li v-for="(item,i) in persons" :key="item.userId">{{item}}-----{{i}}</li>
</ul>
<br>
<br>
<!--遍历对象-->
<h2>汽车信息</h2>
<ul>
<li v-for="(item,i) in car" :key="i">{{item}}-----{{i}}</li>
</ul>
<br>
<br>
<!--遍历字符串-->
<h2>遍历字符串</h2>
<ul>
<li v-for="(item,i) in str" :key="i">{{item}}-----{{i}}</li>
</ul>
<!--遍历指定次数-->
<h2>遍历指定次数</h2>
<ul>
<li v-for="(number,i) in 5" :key="i">{{number}}-----{{i}}</li>
</ul>
</div>
<script>
new Vue({
el:'#root',
data:{
persons:[
{
userId:1,
name:'张三',
age:18
},
{
userId:2,
name:'李四',
age:19
},
{
userId:3,
name:'王五',
age:20
}
],
car:{
name:'奥迪A8',
price:168956,
color:'黑色'
},
str:'hello'
}
})
</script>
4.2 key的基本原理
this.persons.unshift(person),这句代码表示的是把person对象加到persons数组的第一个下标处
如果使用v-for的时候,如果没有指定key的值,那么Vue就默认索引值为key的值
4.3 react 、 Vue中的key的有什么作用
1.虚拟DOM中的作用:
key是虚拟DOM对象的唯一标识,当状态中的数据发生变化的时候,Vue会根据 新数据 生成新的 DOM,随后Vue进行新虚拟DOM与旧的DOM的差异比较;
2.比较规则:
1)旧虚拟DOM中找到与新虚拟DOM相同的key:
①如果新的虚拟DOM中的值没有变化,直接使用真实的DOM
②如果内容变化了,则生成新的真实DOM,随后替换页面中的真实DOM
2)旧虚拟DOM中未找到与新的DOM相同的key:
①创建真实的DOM,之后渲染在页面上。
3.用index(索引)作为key可能会引发的问题:
1)若对数据进行:逆序添加、逆序删除等破坏顺序操作。会产生没有必要的真实DOM的更新 ==> 界面效果没有问题,但是这样的效率会降低
2)如果结构中还包含输入类的DOM时。会产生错误的DOM更新 ==> 这个时候界面存在相应的问题。
4.开发中如何选择key?
1)最好使用每一条数据的唯一标识作为key,比如:id、手机号、身份证号、学号等表示唯一性的值
2)如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表、用于展示数据,使用index作为key的值是没有问题的
5.如果在开发中没有指定key的时候,会默认使用index来作为key的值来使用。