0.案例
一个需求,将一个人姓和名 拼接起来,但是这个人的姓或者名比较长,有可能需要裁剪,但是不希望在HTML中写的太复杂。
比如,出来现实这个人的姓名以外,要求将这个人的姓名中的大小写反转,截取前3位,将某一位变成随机数…..
我们用插值语法可以简单实现此功能:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>vue测试</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> </head> <body> <div id="root"> 姓:<input type="text" v-model="firstName"> </br> 名:<input type="text" v-model="lastName"> </br> 姓名:<span> {{firstName}} -{{lastName}} </span> </div> <script type="text/javascript"> new Vue({ el:'#root', data:{ firstName:"张", lastName:"三" }, methods:{ } }) </script> </body> </html>
我们也可以用methods来实现,比如下面这样:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>vue测试</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> </head> <body> <div id="root"> 姓:<input type="text" v-model="firstName"> </br> 名:<input type="text" v-model="lastName"> </br> 姓名:<span> {{getFullName()}} </span> </div> <script type="text/javascript"> new Vue({ el:'#root', data:{ firstName:"张", lastName:"三" }, methods:{ //拼接名字 getFullName(){ return this.firstName+"-"+this.lastName } } }) </script> </body> </html>
但是这样的效率很低,因为一旦input中的数据改变,那么就会调用getFullName方法。
1.计算属性
首先需要理解什么叫属性,对于vue来讲,data里面的叫属性,比如下面这样:
data:{ firstName:"张", lastName:"三" },
冒号之前的叫属性名,冒号之后 的叫属性值。
计算属性:相当于计算数据,属性等于data里面的数据。比如我们拿firstName和lastName 计算出一个新的属性fullName。但是你不能像下面这样写
data:{ firstName:"张", lastName:"三", fullName:firstName+lastName },
在vue中,属性和计算属性是分开写的,计算属性用computed表示,而且要求把计算的过程定义成一个对象。比如下面这样:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>vue测试</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> </head> <body> <div id="root"> 姓:<input type="text" v-model="firstName"> </br> 名:<input type="text" v-model="lastName"> </br> 姓名:<span> {{fullName}} </span> </div> <script type="text/javascript"> new Vue({ el:'#root', data:{ firstName:"张", lastName:"三" }, computed:{ fullName:{ //get的作用,当有人读取fullName时,get就会被调用,且返回值就作为fullName的值 get(){ console.log("get被调用了") return this.firstName + this.lastName //注意通过this访问 } } }, methods:{ } }) </script> </body> </html>
那么这样写,就可以正常使用计算属性了。
另外,get的调用时机为:
(1)初次读取的时候,会调用。
(2)所依赖的数据发生变化时,比如上面fullName用到了firstName和lastName,当其中任何一个发生改变时,get就会执行。
(3)其余情况,数据会有缓存机制,也就是第一次计算完毕后会把数据缓存,后面调用的过程中直接从缓存中读取数据。
当然, 计算属性中,有get,就有set。但是不是必须,一般你的计算属性主动修改时才会写set ,比如
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>vue测试</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> </head> <body> <div id="root"> 姓:<input type="text" v-model="firstName"> </br> 名:<input type="text" v-model="lastName"> </br> 姓名:<span> {{fullName}} </span> </div> <script type="text/javascript"> new Vue({ el:'#root', data:{ firstName:"张", lastName:"三" }, computed:{ fullName:{ //get的作用,当有人读取fullName时,get就会被调用,且返回值就作为fullName的值 get(){ console.log("get被调用了") return this.firstName + this.lastName }, set(value){ console.log(value) //传入的参数假设是value //下面这个地方可以把拿到的值再赋值给data里面 this.firstName =value } } }, methods:{ } }) </script> </body> </html>
set是一个连锁反应。
2.计算属性的简写
计算属性代码写起来比较长,可以有简写形式,简写形式只有get,没有set。类似于我们写函数。如果去掉set后,我们可以把上面的fullName写成下面两种形式。
fullname:function(){ console.log("哈哈哈哈") return this.firstName+this.lastName } //或者再精简点 fullname(){ console.log("哈哈哈哈") return this.firstName+this.lastName }