Try   HackMD

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。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

我們在script裡打上
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

test表示監聽名稱為test的data,裡面有包immediate和handler,handler表示當監聽的東西改變時就會執行裡面的程式碼,immediate表示是否在剛載入時就執行一次。
我們還可以在handler傳入兩個值。
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

af是修改後的值,be是修改之前的值,有了這兩個值就可以拿來做更進一步的運算。
如果我們想要讓handler寫成function的方式可以改寫成這樣。
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

在handler裡打function名稱,在methods裡做處理。

如果你要監聽的東西是物件型態的話,要改成

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

把監聽的物件改成字串的方式就可以監聽了

程式碼

<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

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

程式碼
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

我們發現了一個問題,當我點了綠色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>