计算属性
定义:如果一个要用的数据,而是由已有的属性(data中的属性)计算得来,那么可以将其作为计算属性
原理:底层借助了Object.defineproperty方法提供的getter和setter。
计算属性都放在vue实例中的computed属性中,computed也是以对象的形式,其中的属性就是一个个计算属性。每个计算属性中又以对象的形式,在其中定义了getter和setter,getter是用于决定计算属性的值,setter用于定义计算属性被修改时变化的规则。
在getter和setter中,要获取data中的属性的值,使用this.属性名
优势:与methods方式实现方式相比,计算属性有着缓冲机制,效率更高,方便调试
注:计算属性最终会出现在vm上,世界读取使用即可。如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生变化
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<script type="text/javascript" src="../vue.js"></script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"><br><br>
名:<input type="text" v-model="lastName"><br><br>
全名:<span>{{fullName}}</span>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
firstName:"张",
lastName:"三"
},
computed:{
fullName:{
//如果有人读取fullName的值时,get就会被调用,且返回值就作为fullName的值
get(){
//此处的this是vm
//get什么时候调用:1.初次读取fullName 2.所依赖的数据发生变化时
return this.firstName + "-" + this.lastName
},
//set什么时候被调用:当fullName被修改时
set(value){
const arr = value.slipt('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
})
</script>
</html>
计算属性的简写方式:
当计算属性只有getter而不使用setter时便可以使用
// 简写形式:
fullName(){
return this.firstName + '-' + this.lastName
}
此时fullName的方法的内容指的就是getter的内容
监视属性
监视属性写在Vue实例的watch属性中,同样,watch也是一个对象的形式,watch的属性就是要监视的属性的key(可以监视data中的属性,也可以监视计算属性),比如要监视data中的name,那么watch中写上一个名为name的key。key可以直接写作属性名,不用引号(原始的写法是写为一个key的字符串)。
在watch的属性中,以对象的形式,写上handler方法,handler方法就是当监视的那个目标属性发生改变的时候,就会调用此handler方法,在此handler方法中写目标属性发生变化时要采取的业务。在watch的属性中,还有一个属性叫immediate,为true时,就是初始化页面时也会调用handler方法
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<script type="text/javascript" src="../vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2><br/>
<button @click="changeWeather">切换天气</button>
</div>
</body>
<script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot?"热":"冷"
}
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot:{ //原始写法是'isHot':{……
//当isHot发生变化的时候调用handler,有两个参数:newValue(变化后的值),oldValue(变化前的值)
handler(newValue,oldValue){
console.log("温度变化了:"+oldValue+'-->'+newValue)
},
//该属性的作用是为true时,初始化时,也会调用handler方法
immediate:true
}
}
})
//写法二,直接使用vm来配置监视属性
// vm.$watch('isHot',{ //第一个参数是监视的属性的名称,第二个参数是同上的isHot:……中的内容一样
// //当isHot发生变化的时候调用handler,有两个参数:newValue(变化后的值),oldValue(变化前的值)
// handler(newValue,oldValue){
// console.log("温度变化了:"+oldValue+'-->'+newValue)
// },
// //该属性的作用是为true时,初始化时,也会调用handler方法
// immediate:true
// })
</script>
</html>
深度监视
如果data中有多级的属性,比如data中有一个属性A是对象的类型,要监视此属性A的内部属性a1,在监视的时候,就要使用引用的方式,但是不能直接写key的名字了,要写原始的字符串形式的key:
watch:{
'A.a1'
handler(newValue,oldValue){
……
},
}
}
如果要检测的是A中一旦有内部属性发生变化,此时就要使用与handler同级的deep属性,设置为true就是会检测监视的属性的所有内部属性
watch:{
A:{
deep:true,
handler(newValue,oldValue){
……
},
}
}
监视的简写形式
当监视不需要设置deep属性进行深度监视以及不使用immediate属性初始化调用handler的时候,就可以使用监视的简写形式,类似于计算属性的简写形式,isHot作为一个方法的形式出现的时候,就是监视isHot属性,并且此方法就代表监视isHot的handler方法,例:
watch:{
//简写形式
isHot(newValue,oldValue){
console.log("温度变化了:"+oldValue+'-->'+newValue)
}
}
使用vm的$watch的简写:function就是代表handler方法
vm.$watch('isHot',function(oldValue,newValue){
console.log("温度变化了:"+oldValue+'-->'+newValue)
})
computed与watch的对比
区别:
- computed能完成的功能,watch都能完成。
- watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
注:
- 被vue管理的函数,最好写成普通函数,这样this的指向才是vm或者组件实例对象。
- 所有不被vue管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数,这样this指向的才是vm或者组件实例对象
绑定样式
绑定class样式
当样式的类名不确定的时候,需要动态指定的时候,就可以使用 :class=”表达式” 来指定样式,可以指定多个:class,最终的效果其实是汇总为一个class样式里面,比如:
<div class=”basic” :class=”mood”></div>,mood属性的值为happy,结果出来其实就是class=”basic happy”。
案例:点击区域后切换该区域指定的颜色为happy或sad
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<script type="text/javascript" src="../vue.js"></script>
<style>
.basic{
height: 600px;
width: 800px;
}
.happy{
background-color: aqua;
}
.sad{
background-color: blanchedalmond;
}
</style>
</head>
<body>
<div id="root">
<h3>你好,{{name}} </h3><br/>
<div class="basic" :class="mood" @click="changeMood"></div>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'李二狗',
mood:'happy',
moodType:true
},
methods: {
changeMood(){
this.moodType = !this.moodType
if(this.moodType == true){
this.mood = 'happy'
}else{
this.mood = 'sad'
}
}
},
})
</script>
</html>
关于:class=”表达式”的表达式的其他写法
数组写法:
其中 :class=”表达式“ 的这个表达式还可以是一个字符串数组,其中的字符串元素的值就是样式的class的名字的字符串,便可以更灵活地改变样式的个数、类型 。
对象写法:
这个表达式还可以是一个对象,这个对象的写法有个格式:这个对象的属性的属性名为样式的class名,属性值为boolean类型的,为true就是应用此样式,为false就是不应用此样式。这种方式通常用于变化的样式个数和类型已经确定,动态改变的只是对应样式是应用还是不应用的情况
classObj:{
happy:true,
sad:false
}
绑定style样式
绑定style的样式的方式是使用:style=”对象/数组”,对象的格式为:对象的属性的属性名为样式类型名称(样式的名称要从短横线式变成驼峰式,比如font-size变为fontSize),属性值为样式的值。
styleObj:{
fontSize:'10px',
backgroundColor:'red'
}
还可以使用数组的写法,数组的元素就是如上的代表样式的对象。