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,否則在頁面中無法獲取到計(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,否則在頁面中無法獲取到計(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)文章
vue實(shí)現(xiàn)動(dòng)態(tài)控制表格列的顯示隱藏
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)動(dòng)態(tài)控制表格列的顯示隱藏,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04vue、react等單頁面項(xiàng)目應(yīng)該這樣子部署到服務(wù)器
這篇文章主要介紹了vue、react等單頁面項(xiàng)目應(yīng)該這樣子部署到服務(wù)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01對(duì)Vue2 自定義全局指令Vue.directive和指令的生命周期介紹
今天小編就為大家分享一篇對(duì)Vue2 自定義全局指令Vue.directive和指令的生命周期介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08vue引入子組件命名不規(guī)范錯(cuò)誤的解決方案
這篇文章主要介紹了vue引入子組件命名不規(guī)范錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04解決vue動(dòng)態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問題
這篇文章主要介紹了解決vue動(dòng)態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08深入淺析Vue不同場(chǎng)景下組件間的數(shù)據(jù)交流
探通過本篇文章給大家探討不同場(chǎng)景下組件間的數(shù)據(jù)“交流”的Vue實(shí)現(xiàn)方法,感興趣的朋友一起看看吧2017-08-08vue在antDesign框架或elementUI框架組件native事件中觸發(fā)2次問題
這篇文章主要介紹了vue在antDesign框架或elementUI框架組件native事件中觸發(fā)2次問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue儲(chǔ)存storage時(shí)含有布爾值的解決方案
這篇文章主要介紹了vue儲(chǔ)存storage時(shí)含有布爾值的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06