HI!大家好啊!緊接著computed之後,今天再來學習新的Vue.js的屬性watch吧!
如果我們要在一個表單上的值發生改變的時候,去執行某些事件,例如判斷輸入資料的格式正不正確,第一個想到的應該是以下的做法:
HTML
<div id="nameVue">
    <input id="name" v-model="name" @change="checkName" />
  <span style="color:red">{{alertMessage}}</sapn>
</div>
JavaScript
//資料
let nameData = {
    name : 'Tom Cruise',
    alertMessage : '',
}
//方法
let nameMethod = {
    //檢查姓名格式
    checkName : () => {
        let newName = document.getElementById('name').value
        if(newName.trim().indexOf(' ') == -1){
            nameData.alertMessage = '請輸入正確的姓名格式'
        }
        else
            nameData.alertMessage = ''
    }
}
let nameVue = new Vue({
    el:'#nameVue',
    data:nameData,
    methods:nameMethod,
})
我們可以透過v-on來處理onchange事件,達到我們要的成果:
但是如果我們使用onchange事件的話,就必須在移除焦點時才會觸發相對應的事件,那有辦法在值改變的時候就馬上知道嗎?
欸嘿嘿!有的!接著讓我們把watch給請出來吧!
基本上watch能夠在某個監聽值發生改變的時候進行異步的響應,有點類似JavaScript上的監聽器addEventListener(),不過他是對物件內的值做監聽,來看看使用方法吧!
HTML
<div id="nameVue">
    <input id="name" v-model="name"/>
    <span style="color:red">{{alertMessage}}</sapn>
</div>
JavaScript
//資料
let nameData = {
    name : 'Tom Cruise',
    alertMessage : '',
}
//方法
let nameMethod = {
    //檢查姓名格式
    checkName : (newName,oldName) => {
        if(newName.trim().indexOf(' ') == -1)
            nameData.alertMessage = '請輸入正確的姓名格式'
        else
            nameData.alertMessage = ''
    }
}
let nameVue = new Vue({
    el:'#nameVue',
    data:nameData,
    watch:{
        /*對name值進行監聽,只要name改變了,就會觸發程式
        newVal為更改後的值,oldVal更改前的值*/
        name: (newVal,oldVal) => {
            //呼叫nameMethod的function
            nameMethod.checkName(newVal)
        }
    }
})
上方例子中,我們原本綁定在input的@change拿掉,並在Vue的物件中增加了一個新的物件屬性watch,watch中的name屬性即是要進行監聽的屬性,並在屬性值改變時執行function,另外可以發現,在執行的function中有兩個參數newVal和oldVal,這兩個參數是Vue幫忙處理的,第一個參數傳入更改過後的值,第二個為更改前的值,經過以上方式,即使在輸入中也可以捕捉每一次和前一次變動的內容,以及變動時要使用的函式,便不需要在離開焦點才能執行function看到結果,如下:
watch的運作主要是因為v-model幫我們做了兩件事情
v-bind單向綁定資料,會因為每次綁定值的變動同步更新到View上。v-on:input去偵測每次值的變動,觸發更新v-bind綁定的值。參考文章:https://blog.csdn.net/u010320804/article/details/79486034
以上補充也會同步更新到[筆記][Vue.js]打開Vue.js世界的大門(4)-讓雙向綁定抓住你的資料
而watch的原理是因為v-model幫我們做了v-on:input的關係,這會導致我們每次的更新資料的時候,都重新把新值透過存取器的setter寫到綁定的屬性中,主角watch就會在這個時候藉由setter觸發,執行watch中綁定的事件,執行完後後再用getter把值重新綁定到畫面!
參考文章:https://segmentfault.com/a/1190000010014281
話說,官方在說明watch的例子時真的很簡單就帶過了,感覺對他有點偏心XD,不過以上表單驗證的例子也是我目前想的到watch在實務上可以用到的地方,其他可能要等到某天預到什麼需求,才會想起「對了!我可以用watch處理!」這樣子吧XD,如果有大大在實務上watch應用的地方也歡迎留言分享!
最後這篇短短的watch屬性應該不難懂(結果我也偏心給他最少的章節XD)!如果文章中有任何解釋錯誤、講解不清楚的地方,在請各位大大留言告訴我,我會盡快修改文章內容的!謝謝大家的觀賞
你該不會在準備鐵人賽的資料吧
已經發過的文章應該不能在放鐵人賽吧XD
不過我倒是有想說用React參賽
沒規定不行啊
哈哈哈,小魚大大我們一起參賽啊XD
今年有參加啊,明年看有沒有時間吧,還沒想到要用什麼主題...要不然unity也是可以,只是怕學習速度沒那麼快...不過可以把現在學的到時候拿出來用...
我也很怕沒時間,哈哈哈。
大大下手unity了哦!很期待開發出來的遊戲XD
目前還在摸2D而已,還沒進展到3D的階段...
好奇去查了一下 watch 的原理,細節感覺蠻深奧的,有機會再深入研究,哈哈哈。
不過大致流程如下:
對耶!
我沒有注意到這點
我有試著把上方的@change改成@input果然就可以得到和watch一樣的效果了!
之前都沒有注意過這個事件
我會再修改一下文章中的內容,感謝大大補充!
哈哈哈,我也是今天查資料才發現 oninput 事件,textbox 會觸發 oninput 其實是因為 v-model 的語法糖。
<input v-model="name" />
//等於
<input v-bind:value="name" v-on:input="name=$event.target.value" />
真的很感謝大大的補充,
我已經把查到的資訊放到文章中了!
如果有理解錯的話還麻煩大大告訴我
話說其實我一直沒有去研究過Vue的生命週期是怎麼運作,
想說之後是不是應該要發一篇文來講這個東西