Vue属性篇_侦听器watch
作用:偵聽屬性,響應數據(data&computed)的變化,當數據變化時,會立即執行對應函數,其屬性值可以為函數、字符串、對象和數組。
1.屬性值類型
(1)函數類型
函數類型中,被偵聽的數據作為函數名,當數據改變時,執行 watch() 中對應的函數,該函數可以接受兩個參數,第一個參數是 newVal(改動后的數據),第二個參數是 oldVal (改動前的數據),如下例
<div id="app">{{ bookName }} </div> const vm = new Vue({el: '#app',data: {bookName: '《JavaScript設計模式》'},watch: {bookName(newVal, oldVal) {console.log('newVal:', newVal)console.log('oldVal:', oldVal)}} })【結果】在控制臺改變bookName的值,打印結果如下
(2)字符串類型
key 為 被偵聽的數據,value 為方法名字,當被偵聽的數據改變時,會執行該方法,如下例
<div id="app">{{ bookName }} </div> const vm = new Vue({el: '#app',data: {bookName: '《JavaScript設計模式》'},methods:{bookNameChange(){console.log(this.bookName);}},watch: {bookName: 'bookNameChange'} })【結果】
(3)對象類型
對象類型包含3個屬性,handle函數(必選),deep和immediate(可選)?
1)handler
handler 為被偵聽的數據改變時執行的回調函數,其值類型為函數 / 字符串(函數名)
<div id="app">{{ bookName }} </div> const vm = new Vue({el: '#app',data: {bookName: '《JavaScript設計模式》',},watch: {bookName: {handler() {console.log(this.bookName)}}} })【結果】改變 bookName 的值,執行 handler?函數
2)deep?
在默認情況下,偵聽器偵聽對象只偵聽引用的變化,只有在給對象賦值時它才能被監聽到,所以需要使用 deep 選項,讓其可以發現對象內部值得變化,講 deep 得值設置為 true,那么無論該對象被嵌套得有多深,都可以被偵聽到。但是當對象的屬性較多時,性能開銷比較大。因此可以選擇只偵聽對象的某個屬性
【例1】
<div id="app">{{ book.press }} </div> const vm = new Vue({el: '#app',data: {book: {bookName: '《JavaScript設計模式》',press: '人民郵電出版社',writer: 'Addy'}},watch: {book: {handler() {console.log('book.press變化了')},deep: true}} })【結果】
3)immediate
immediate 選項可以使偵聽開始后立刻被調用,而不是等待偵聽的數據更改后才會調用
<div id="app">{{ book.press }} </div> const vm = new Vue({el: '#app',data: {book: {bookName: '《JavaScript設計模式》',press: '人民郵電出版社',writer: 'Addy'}},watch: {book: {handler() {console.log('handler執行了')},deep: true,immediate: true}} })【結果】
?4)只偵聽對象的某個屬性
將對象的屬性放在字符串中當作函數名,當該對象中的該屬性值發生變化時,執行回調函數
<div id="app">{{ book.press }} </div> const vm = new Vue({el: '#app',data: {book: {bookName: '《JavaScript設計模式》',press: '人民郵電出版社',writer: 'Addy'}},watch: {'book.press'() {console.log('book.press改變了')}} })【結果】
(4)數組類型
將多種不同值類型寫在一個數組中,如下例
<div id="app">{{ bookName }} </div> const vm = new Vue({el: '#app',data: {bookName: '《JavaScript設計模式》'},methods: {bookNameChange() {console.log('運行bookNameChange函數')}},watch: {//字符串// bookName:['bookNameChange']//函數// bookName:[function () {// console.log('bookName改變了')// }]//對象// bookName:{// handler(){// console.log('運行handler函數')// },// deep:true,// immediate:true// }//全部bookName: ['bookNameChange',function () {console.log('運行watch中的函數')},{handler() {console.log('運行handler函數')},deep: true,immediate: true}]} })【結果】
2.vm.$watch
Vue 實例將會在實例化時調用 $watch,遍歷 watch 對象的每一個屬性,我們也可以利用 vm.$watch 來實現偵聽,用法如下
(1)偵聽某個數據
有兩種方法,第一種接收三個參數,第一個為被偵聽的數據,第二個為數據改變時執行的回調函數,第三個可選,為設置的選項;第二種接受兩個參數,第一個參數為被偵聽的數據,第二個參數為選項對象,其中 handler 函數是數據改變時執行的回調函數,其他屬性可選。
【例1】三個參數
<div id="app">{{ book.bookName }} </div> const vm = new Vue({el:'#app',data:{book:{bookName:"《JavaScript設計模式》"}} }) vm.$watch('book',function () {console.log('bookName has changed') },{deep: true,immediate:true })?【結果】
【例2】兩個參數
const vm = new Vue({el:'#app',data:{book:{bookName:"《JavaScript設計模式》"}} }) vm.$watch('book',{handler(){console.log('bookName has changed')},deep:true,immediate:false })?【結果】
(2)偵聽某個對象屬性
傳參情況同上,舉例如下
vm.$watch('book.bookName',{handler(){console.log('bookName has changed')} })【結果】?
(3) 偵聽數據由多個數據得到
當偵聽的數據在初始不確定,由多個數據得到時,此時可以將第一個參數寫成函數形式,當任何依賴的數據改變時,執行回調函數,如下
<div id="app">{{ bookName }}{{ writer }} </div> const vm = new Vue({el: '#app',data: {bookName: "《JavaScript設計模式》",writer: 'Addy'} }) vm.$watch(function () {// 相當于監聽了一個未被定義的計算屬性return this.bookName + this.writer },function () {// 當bookName或者writer改變時,執行該函數console.log('At least one of them changed') })【結果】
【注】在偵聽器函數執行后,會返回一個取消偵聽器函數, 用來停止觸發回調;在帶有immediate選項時,不能再第一次回調時取消偵聽數據,寫法如下
const vm = new Vue({el: '#app',data: {bookName: "《JavaScript設計模式》",writer: 'Addy'} }) //這里只能用var申明變量 var unwatch = vm.$watch('bookName',function () {if (unwatch) { //確保unwatch存在才能調用取消偵聽函數unwatch();}console.log('bookName changed') },{immediate:true })?【結果】
?3.偵聽器與計算屬性比較
(1)兩者都可以觀察和響應 Vue 實例上的數據的變動
(2)watch 擅長處理的場景時:一個數據影響多個數據;計算屬性擅長處理的場景是:多個數據影響一個數據;
(3)計算屬性不能執行異步,因為其有返回值,是同步執行的;偵聽器中可以執行異步,可以用來發送請求。
<div id="app">{{ question }} </div> var vm = new Vue({el: '#app',data: {question: '',},watch: {question () {setTimeout(() => {alert(this.question);}, 2000)}} })總結
以上是生活随笔為你收集整理的Vue属性篇_侦听器watch的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: H5新增API_geoLocation
- 下一篇: Vue_异步加载_vue-resourc