0%

Vue 筆記 - 向外層傳遞事件 emit

vue.js

拆分元件後的資料獨立,好處是彼此不會受影響,只要關注於元件本身即可,但有時候還是需要向外傳遞資料,這時就可以使用 emit 來處理。

練習範例 - 資料傳遞至父層

點擊子層的按鈕,將累加的資料傳遞到父層來顯示。

首先先確認在 Vue 的物件實體中是否能實作這個功能,h2 下方加上一個按鈕。

HTML

1
2
3
4
5
6
7
8
9
<div id="app">
<h2>透過 emit 向外傳遞資訊</h2>
我透過元件儲值了 {{ cash }} 元
<button class="btn btn-primary">click</button>

<button-counter></button-counter>
<hr />
<button-counter></button-counter>
</div>

局部元件與 Vue 實體

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  <script type="text/x-template" id="buttonCounter">
<div>
<button @click="incrementCounter" class="btn btn-outline-primary">增加 {{ counter }} 元</button>
<input type="number" class="form-control mt-2" v-model="counter">
</div>`
</script>


<script>
Vue.component('buttonCounter', {
template: `#buttonCounter`,
data: function () {
return {
counter: 1
}
},
methods: {

}
});
//Vue 物件實體
var app = new Vue({
el: '#app',
data: {
cash: 300
},
methods: {

}
});
</script>

觸發事件

在 HTML 中要用 button 來觸發事件,使用 v-on:click,並在 methods 中建立方法屬性與要執行的內容。

HTML

建立點擊事件。

1
2
3
4
5
6
7
8
9
<div id="app">
<h2>透過 emit 向外傳遞資訊</h2>
我透過元件儲值了 {{ cash }} 元
<button @click="incrementTotal" class="btn btn-primary">click</button>

<button-counter @click="incrementTotal"></button-counter>
<hr />
<button-counter></button-counter>
</div>

Vue

將對應的方法寫入 methods

1
2
3
4
5
6
7
8
9
10
11
var app = new Vue({
el: "#app",
data: {
cash: 300,
},
methods: {
incrementTotal() {
this.cash += 1;
},
},
});

於局部元件註冊點擊事件

確認可以實作累加功能後,在局部元件加入點擊事件,並且啟用上方寫好的 incrementTotal 的方法內容,於局部元件的 vue 物件中寫入該屬性。

HTML

1
2
3
4
5
6
7
8
<div id="app">
<h2>透過 emit 向外傳遞資訊</h2>
我透過元件儲值了 {{ cash }} 元
<button @click="incrementTotal" class="btn btn-primary">click</button>
<button-counter @increment="incrementTotal"></button-counter>
<hr />
<button-counter></button-counter>
</div>

局部元件

1
2
3
4
5
6
   <script type="text/x-template" id="buttonCounter">
<div>
<button @click="incrementCounter" class="btn btn-outline-primary">增加 {{ counter }} 元</button>
<input type="number" class="form-control mt-2" v-model="counter">
</div>`
</script>

Vue

於局部元件內的方法,透過 $emit() 的方式將可以觸發父層的 @click="incrementTotal" 點擊事件,emit 前面要加一個 $ 字號,裡面帶入局部元件的事件名稱(此名稱可自訂)

1
2
3
4
5
6
7
8
9
10
11
12
13
Vue.component("buttonCounter", {
template: `#buttonCounter`,
data: function () {
return {
counter: 1,
};
},
methods: {
incrementCounter() {
this.$emit("increment");
},
},
});

就完成點擊內部元件觸發外層事件,讓數字可以往上壘加。

emit 是可以傳遞參數的,其參數就是 this.counter,也就是局部元件中的 counter 的值。

1
2
3
4
5
data: function () {
return {
counter: 1
}
}

但為了確保傳入的值為數字型別,所以外面使用 Number 將 this.counter 包起來。

1
2
3
4
5
methods: {
incrementCounter(){
this.$emit('increment'Number(this.counter));
}
}

改寫 Vue 物件實體

如果在另一個按鈕要改變輸入的值,並將其值累加於父層上,在 Vue 物件實體的方法中,帶入參數 newNumber,在將原本累加的程式碼改寫成下方程式碼,就可以完成在子層設定的值,累加到父層上。

1
2
3
4
5
6
7
8
9
10
11
var app = new Vue({
el: "#app",
data: {
cash: 300,
},
methods: {
incrementTotal(newNumber) {
this.cash = this.cash + newNumber;
},
},
});