# vue watch computed v-on 7 ###### tags: `vue` 基本概念 這次我們來說明watch、computed、v-on的用法, watch有點像是監聽的概念,當監聽的值或物件有變動時,就會觸發watch裡的程式。 computed和watch有點像,但他不能抓修改前後的值,有緩存機制,相依data,主要用來減少template裡的邏輯運算。 v-on也算是監聽,簡寫為@。 --- ### 實作 #### watch 先來做簡單的監聽data,先新增一個data叫test,再新增一個input,v-model test。 ![](https://i.imgur.com/jJ4YmP9.jpg) 我們在script裡打上 ![](https://i.imgur.com/7R6oY19.jpg) test表示監聽名稱為test的data,裡面有包immediate和handler,handler表示當監聽的東西改變時就會執行裡面的程式碼,immediate表示是否在剛載入時就執行一次。 我們還可以在handler傳入兩個值。 ![](https://i.imgur.com/HcagfUq.jpg) af是修改後的值,be是修改之前的值,有了這兩個值就可以拿來做更進一步的運算。 如果我們想要讓handler寫成function的方式可以改寫成這樣。 ![](https://i.imgur.com/TwVias3.jpg) ![](https://i.imgur.com/WoA1Wan.jpg) 在handler裡打function名稱,在methods裡做處理。 如果你要監聽的東西是物件型態的話,要改成 ![](https://i.imgur.com/BRc07ss.jpg) ![](https://i.imgur.com/z24079w.jpg) 把監聽的物件改成字串的方式就可以監聽了 程式碼 ``` <template> <div class="home"> <input type="text" v-model="obj.a"> <br> <p>之前:{{oldvalue}}</p> <br> <p>現在:{{newvalue}}</p> </div> </template> <script> // @ is an alias to /src /*eslint-disable*/ export default { name: 'watch', components: { }, data:()=>({ dd:5, obj:{ a:42, b:55 }, test:"asd", newvalue:"", oldvalue:"" }), watch:{ test:{ immediate:false, handler(af,be){ this.newvalue = af this.oldvalue = be console.log("change") } }, dd:{ handler:"ddhandle", immediate:false }, "obj.a":{ immediate:false, handler(af,be){ this.newvalue = af this.oldvalue = be console.log("change") } }, }, methods:{ ddhandle(af,be){ this.newvalue = af this.oldvalue = be console.log(be+" change "+af); } }, } </script> ``` --- #### computed ``` <template> <div class="home"> <input type="text" v-model="gg"> <p>{{reversegg}}</p> </div> </template> <script> // @ is an alias to /src /*eslint-disable*/ export default { name: 'watch', components: { }, data:()=>({ gg:"i am student" }), computed:{ reversegg() { return this.gg.split('').reverse().join(''); }, }, } </script> ``` 新增一個data叫gg,在computed裡打要做計算的值。 computed主要是做data資料的計算(因為data無法計算或放判斷式),一般我們要反轉字串都會直接在template做反轉,有了computed就可以讓程式碼更易讀。 --- #### v-on 大部分的html標籤都可以放@,基本樣式為 ``` @事件="內容" 範例: <button class="btn btn-dark" @click="dd+=1">dark</button> ``` 事件為觸發內容的方式有click、change、mouseover等... 達成事件後就會執行內容 v-on還可以做其他修飾 我們先做3個div ![](https://i.imgur.com/MLmtskH.jpg) 程式碼 ![](https://i.imgur.com/TSMkp4A.jpg) 我們發現了一個問題,當我點了綠色div會觸發a、b、c三個function 那我要怎阻止這個問題? --- 把程式碼改成 ``` <div id="a" @click.self="a()"> <div id="b" @click.self="b()"> <div id="c" @click.self="c()"> </div> </div> </div> ``` .self 只會點擊本元素才會執行,並不會由其他元素間接執行 --- 也可以改成 ``` <div id="a" @click="a()"> <div id="b" @click.stop="b()"> <div id="c" @click.stop="c()"> </div> </div> </div> ``` .stop 會在觸發後阻止點擊事件向父元素傳遞 --- 當然還有其他修飾字符 .capture 一般我們點擊最小的div時會由子到父觸發function,有了capture我們點擊最小的div會由父到子觸發function ``` <div id="a" @click.capture="a()"> <div id="b" @click.capture="b()"> <div id="c" @click.capture="c()"> </div> </div> </div> ``` --- .once 很簡單,就是只會觸發一次 ``` <div id="a" @click.once="a()"> <div id="b" @click.once="b()"> <div id="c" @click.once="c()"> </div> </div> </div> ```