Vue 基礎(chǔ)語法之計(jì)算屬性(computed)、偵聽器(watch)、過濾器(filters)詳解
1、Vue 實(shí)例選項(xiàng)
在實(shí)例化Vue對(duì)象時(shí),需要為Vue的構(gòu)造函數(shù)提供一系列的配置信息,代碼如下:
new Vue({
//選項(xiàng)
})當(dāng)使用 new 操作符創(chuàng)建 Vue 實(shí)例時(shí),可以為實(shí)例傳入一個(gè)選項(xiàng)對(duì)象,選項(xiàng)對(duì)象中有很多類型的數(shù)據(jù),具體內(nèi)容如下:
- 數(shù)據(jù)選項(xiàng):data、props、propsData、computed、methods、watch
- DOM選項(xiàng):el、template、render、renderError
- 生命周期選項(xiàng):beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed、activated、deactivated、errorCaptured
- 資源選項(xiàng):directives、filters、components
- 組合選項(xiàng):parent、mixins、extends、provide、inject
- 其他選項(xiàng):name、delimiters、functional、model、inheritAttrs、comments
對(duì)于選項(xiàng)的學(xué)習(xí),大家可以參考 Vue 官網(wǎng)的 API 文檔,本章教程中只對(duì) Vue 中的計(jì)算屬性、過濾器、偵聽器三個(gè)核心的選項(xiàng)做講解。
2、計(jì)算屬性(computed)
2.1、computed 的基本用法
計(jì)算屬性就是 Vue 實(shí)例選項(xiàng)中的 computed,computed 的值是一個(gè)對(duì)象類型,對(duì)象中的屬性值為函數(shù),而且這個(gè)函數(shù)沒辦法接收參數(shù),如果想為某個(gè)計(jì)算屬性傳參的話,可以使用閉包的方式。
這里需要注意的是,計(jì)算屬性不能聲明為箭頭函數(shù)! 因?yàn)榧^函數(shù)中的 this 指向的是上下文中的 this,這樣就不能在計(jì)算屬性的函數(shù)中獲取 Vue 實(shí)例對(duì)象 this 了。
計(jì)算屬性有以下特點(diǎn):
- 模板中放入太多的邏輯會(huì)讓模板過重且難以維護(hù),使用計(jì)算屬性可以讓模板更加的簡(jiǎn)潔。
- 計(jì)算屬性是基于它們的響應(yīng)式依賴進(jìn)行緩存的。
- computed比較適合對(duì)多個(gè)變量或者對(duì)象進(jìn)行處理后返回一個(gè)結(jié)果值,也就是數(shù)多個(gè)變量中的某一個(gè)值發(fā)生了變化則我們監(jiān)控的這個(gè)值也就會(huì)發(fā)生變化。
示例代碼:
<div id="app">
<p>{{ total }}</p>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
a: 1
},
computed: {
total(n) {
return this.a + 5
}
}
})
</script>
在瀏覽器中運(yùn)行的結(jié)果如下:

2.2、computed 作為函數(shù)傳參
computed 對(duì)象的屬性值雖然是聲明為函數(shù),computed 的用法是和 data 一樣的,作為屬性使用,如果要把 computed 作為函數(shù)使用,可以返回一個(gè)閉包函數(shù)。示例代碼如下:
<div id="app">
<p>{{ total(6) }}</p>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
a: 1
},
computed: {
total() {
return (n) => {
return this.a + n
}
}
}
})
</script>
在瀏覽器中運(yùn)行的效果如下:

2.3、計(jì)算屬性和函數(shù)的區(qū)別
雖然計(jì)算屬性(computed)和函數(shù)(methods)的聲明過程是很相似的,但是功能上還是有所差別的,其中最大的區(qū)別就是 計(jì)算屬性可以根據(jù)它所依賴的響應(yīng)式數(shù)據(jù)進(jìn)行緩存 ,簡(jiǎn)單來說,就是在計(jì)算屬性聲明的函數(shù)中,如果染回值依賴了 data 中聲明的響應(yīng)式數(shù)據(jù)的話,只有當(dāng)依賴的 data 中的數(shù)據(jù)發(fā)生變化時(shí),當(dāng)前的計(jì)算屬性函數(shù)才會(huì)重新執(zhí)行,否則的話就直接獲取上次執(zhí)行后緩存的結(jié)果。這樣做的好處是可以提高性能,減少不必要的重復(fù)運(yùn)算。
示例代碼如下:
<div id="app">
<!--
當(dāng)多次調(diào)用 reverseString 的時(shí)候
只要里面的 num 值不改變 他會(huì)把第一次計(jì)算的結(jié)果直接返回
直到data 中的num值改變 計(jì)算屬性才會(huì)重新發(fā)生計(jì)算
-->
<div>{{reverseString}}</div>
<div>{{reverseString}}</div>
<!-- 調(diào)用methods中的方法的時(shí)候 他每次會(huì)重新調(diào)用 -->
<div>{{reverseMessage()}}</div>
<div>{{reverseMessage()}}</div>
</div>
<script type="text/javascript">
/*
計(jì)算屬性與方法的區(qū)別:計(jì)算屬性是基于依賴進(jìn)行緩存的,而方法不緩存
*/
var vm = new Vue({
el: '#app',
data: {
msg: 'Nihao',
num: 100
},
methods: {
reverseMessage: function(){
console.log('methods')
return this.msg.split('').reverse().join('');
}
},
//computed屬性的聲明和data屬性、methods屬性是平級(jí)關(guān)系
computed: {
//reverseString屬性名稱是自定義的
reverseString: function(){
console.log('computed')
var total = 0;
// 當(dāng)data中num 屬性的值發(fā)生改變時(shí),reverseString 函數(shù)會(huì)自動(dòng)進(jìn)行計(jì)算
for(var i=0;i<=this.num;i++){
total += i;
}
// 在reverseString函數(shù)中必須要有return,否則在頁(yè)面中無法獲取到計(jì)算后的值
return total;
}
}
});
</script>
2.4、計(jì)算屬性的 getter 和 setter 函數(shù)
計(jì)算屬性雖然可以像 data 屬性一樣取值,但是如果要對(duì)計(jì)算屬性賦值的話,必須使用 setter 方法,示例代碼如下:
<div id="app">
<!--
當(dāng)多次調(diào)用 reverseString 的時(shí)候
只要里面的 num 值不改變 他會(huì)把第一次計(jì)算的結(jié)果直接返回
直到data 中的num值改變 計(jì)算屬性才會(huì)重新發(fā)生計(jì)算
-->
<div>{{reverseString}}</div>
<div>{{reverseString}}</div>
<!-- 調(diào)用methods中的方法的時(shí)候 他每次會(huì)重新調(diào)用 -->
<div>{{reverseMessage()}}</div>
<div>{{reverseMessage()}}</div>
</div>
<script type="text/javascript">
/*
計(jì)算屬性與方法的區(qū)別:計(jì)算屬性是基于依賴進(jìn)行緩存的,而方法不緩存
*/
var vm = new Vue({
el: '#app',
data: {
msg: 'Nihao',
num: 100
},
methods: {
reverseMessage: function(){
console.log('methods')
return this.msg.split('').reverse().join('');
}
},
//computed屬性的聲明和data屬性、methods屬性是平級(jí)關(guān)系
computed: {
//reverseString屬性名稱是自定義的
reverseString: function(){
console.log('computed')
var total = 0;
// 當(dāng)data中num 屬性的值發(fā)生改變時(shí),reverseString 函數(shù)會(huì)自動(dòng)進(jìn)行計(jì)算
for(var i=0;i<=this.num;i++){
total += i;
}
// 在reverseString函數(shù)中必須要有return,否則在頁(yè)面中無法獲取到計(jì)算后的值
return total;
}
}
});
</script>
點(diǎn)擊重新計(jì)算按鈕之前:

點(diǎn)擊重新計(jì)算按鈕之后:

在 reset() 函數(shù)中為計(jì)算屬性 total 賦值,會(huì)被計(jì)算屬性中的 set() 函數(shù)接收,然后再把值傳給 data 中的 a 變量,那么此時(shí)獲取到的計(jì)算屬性值就是更新后的 a 變量 +5 之后的結(jié)果。
3、偵聽器(watch)
3.1、watch 的基本用法
watch是監(jiān)聽器,其值為一個(gè)對(duì)象,對(duì)象中的屬性值可以為函數(shù)、對(duì)象和數(shù)組。當(dāng)data中的一個(gè)屬性需要被觀察期內(nèi)部值的改變時(shí),可以通過watch來監(jiān)聽data屬性的變化。
watch監(jiān)聽器的基本用法如下:
- 使用watch來響應(yīng)數(shù)據(jù)的變化
- 一般用于異步或者開銷較大的操作
- watch 中的屬性 一定是data 中 已經(jīng)存在的數(shù)據(jù)
- 當(dāng)需要監(jiān)聽一個(gè)對(duì)象的改變時(shí),普通的watch方法無法監(jiān)聽到對(duì)象內(nèi)部屬性的改變,只有data中的數(shù)據(jù)才能夠監(jiān)聽到變化,此時(shí)就需要deep屬性對(duì)對(duì)象進(jìn)行深度監(jiān)聽
示例代碼:
<!-- 驗(yàn)證用戶名 -->
<div id="app">
<div>
姓:<input type="text" v-model='lastName'>
</div>
<div>
名:<input type="text" v-model='firstName'>
</div>
<div>
全名:{{fullName}}
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
firstName: '張',
lastName: '三'
},
// 計(jì)算屬性
watch: {
firstName(val) {
this.fullName = val + ' ' + this.lastName;
},
lastName(val) {
this.fullName = this.firstName + ' ' + val;
}
}
});
</script>watch 對(duì)象中的 firstName 對(duì)應(yīng)著 data 中的 firstName ,當(dāng) firstName 值發(fā)生改變時(shí)會(huì)自動(dòng)觸發(fā) watch 中的 firstName() 函數(shù)的執(zhí)行。同理,watch 中的 lastName 對(duì)應(yīng)的也是 data 中的 lastName。
watch 對(duì)象中的函數(shù)屬性的參數(shù)有兩個(gè),參數(shù)一是對(duì)應(yīng) data 中相同變量名屬性被修改后的新值,參數(shù)二是該 data 屬性修改前的舊值。
3.2、偵聽器的配置項(xiàng)
如果要監(jiān)聽的 data 屬性值是一個(gè)對(duì)象或者是數(shù)組,如果對(duì)象嵌套層級(jí)比較深的情況下,需要開啟 watch 的深度監(jiān)聽。示例代碼如下:
new Vue({
el: '#app',
data: {
num: {
a: 1,
b: 2,
c: {
d: 3
}
}
},
watch: {
num: {
deep: true, // 開啟深度監(jiān)聽
handler(val, oldVal) {
//...
}
}
}
})
4、過濾器(filter)
4.1、過濾器有什么用
- Vue.js允許自定義過濾器,可被用于一些常見的文本格式化。
- 過濾器可以用在兩個(gè)地方:雙花括號(hào)插值和v-bind表達(dá)式。
- 過濾器應(yīng)該被添加在JavaScript表達(dá)式的尾部,由“管道”符號(hào)指示
4.2、全局過濾器
Vue 的全局 API 中提供了注冊(cè)全局過濾器的函數(shù) Vue.filter(),全局過濾器注冊(cè)好之后所有的組件可以使用。
全局過濾器示例代碼:
<div id="app">
<input type="text" v-model='msg'>
<!-- upper 被定義為接收單個(gè)參數(shù)的過濾器函數(shù),表達(dá)式 msg 的值將作為參數(shù)傳入到函數(shù)中 -->
<div>{{msg | upper}}</div>
<!--
支持級(jí)聯(lián)操作
upper 被定義為接收單個(gè)參數(shù)的過濾器函數(shù),表達(dá)式msg 的值將作為參數(shù)傳入到函數(shù)中。
然后繼續(xù)調(diào)用同樣被定義為接收單個(gè)參數(shù)的過濾器 lower ,將upper 的結(jié)果傳遞到lower中
-->
<div>{{msg | upper | lower}}</div>
<div :abc='msg | upper'>測(cè)試數(shù)據(jù)</div>
</div>
<script type="text/javascript">
// lower 為全局過濾器
Vue.filter('lower', function(val) {
return val.charAt(0).toLowerCase() + val.slice(1);
});
new Vue({
el: '#app'
})
</script>
4.3、局部過濾器
局部過濾器被聲明在 Vue 實(shí)例對(duì)象選項(xiàng)中的 filters 中,這里需要注意的是,全局注冊(cè)時(shí)是filter,沒有s的,而局部過濾器是filters,是有s的。
局部過濾器注冊(cè)好之后只能在注冊(cè)的組件內(nèi)使用,示例代碼如下:
var vm = new Vue({
el: '#app',
data: {
msg: ''
},
filters: {
upper: function(val) {
return val.charAt(0).toUpperCase() + val.slice(1);
}
}
});
filters 屬性 定義 和 data 已經(jīng) methods 平級(jí),定義 filters 中的過濾器為局部過濾器。上面代碼中的 upper 是自定義的過濾器名字,upper 被定義為接收單個(gè)參數(shù)的過濾器函數(shù),表達(dá)式 msg 的值將作為參數(shù)傳入到函數(shù)中。過濾器中一定要有返回值,這樣外界使用過濾器的時(shí)候才能拿到結(jié)果。
4.4、過濾器串聯(lián)
并且過濾器可以串聯(lián)使用, 在此處是將filter1的值作為filter2的參數(shù)。
{{ data | filter1 | filter2 }}
4.5、過濾器傳參
示例代碼如下:
<div id="box">
{{ message | filterA('arg1', 'arg2') }}
</div>
<script>
Vue.filter('filterA',function(n,a,b){
if(n<10){
return n+a;
}else{
return n+b;
}
});
new Vue({
el:"#box",
data:{
message: "哈哈哈"
}
})
</script>上面代碼中,filterA 被定義為接收三個(gè)參數(shù)的過濾器函數(shù)。其中 message 的值作為第一個(gè)參數(shù),普通字符串 ‘arg1’ 作為第二個(gè)參數(shù),表達(dá)式 arg2 的值作為第三個(gè)參數(shù)。
在過濾器中第一個(gè)參數(shù) 對(duì)應(yīng)的是管道符前面的數(shù)據(jù) n 此時(shí)對(duì)應(yīng) message,第2個(gè)參數(shù) a 對(duì)應(yīng) 實(shí)參 arg1 字符串,第3個(gè)參數(shù) b 對(duì)應(yīng) 實(shí)參 arg2 字符串。
到此這篇關(guān)于Vue 基礎(chǔ)語法之計(jì)算屬性(computed)、偵聽器(watch)、過濾器(filters)詳解的文章就介紹到這了,更多相關(guān)vue計(jì)算屬性偵聽器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用babel-plugin-import?實(shí)現(xiàn)自動(dòng)按需引入方式
這篇文章主要介紹了使用babel-plugin-import?實(shí)現(xiàn)自動(dòng)按需引入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
動(dòng)態(tài)實(shí)現(xiàn)element ui的el-table某列數(shù)據(jù)不同樣式的示例
這篇文章主要介紹了動(dòng)態(tài)實(shí)現(xiàn)element ui的el-table某列數(shù)據(jù)不同樣式的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
詳解Vue如何進(jìn)行分布式事務(wù)管理以及解決方案
在分布式系統(tǒng)中,事務(wù)管理是一個(gè)非常重要的問題,所以本文將介紹一下Vue中如何進(jìn)行分布式事務(wù)管理以及分布式事務(wù)解決方案,希望對(duì)大家有所幫助2023-06-06
vue實(shí)現(xiàn)一個(gè)移動(dòng)端屏蔽滑動(dòng)的遮罩層實(shí)例
本篇文章主要介紹了vue實(shí)現(xiàn)一個(gè)移動(dòng)端屏蔽滑動(dòng)的遮罩層實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下2017-06-06
Vue實(shí)現(xiàn)路由過渡動(dòng)效的4種方法
Vue 路由過渡是對(duì) Vue 程序一種快速簡(jiǎn)便的增加個(gè)性化效果的的方法,這篇文章主要介紹了Vue實(shí)現(xiàn)路由過渡動(dòng)效的4種方法,感興趣的可以了解一下2021-05-05
詳解vuejs中執(zhí)行npm run dev出現(xiàn)頁(yè)面cannot GET/問題
這篇文章主要介紹了詳解vuejs中執(zhí)行npm run dev出現(xiàn)頁(yè)面cannot GET/問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Vue3的路由守衛(wèi)以及登錄狀態(tài)儲(chǔ)存過程
這篇文章主要介紹了Vue3的路由守衛(wèi)以及登錄狀態(tài)儲(chǔ)存過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Vue項(xiàng)目打包部署到GitHub Pages的實(shí)現(xiàn)步驟
本文主要介紹了Vue項(xiàng)目打包部署到GitHub Pages的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04

