# 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>
```