iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 18
0

菜菜菜的 Vue 30天 - Day18

$emit

上一章介紹了父層傳子層的 props,這章就來介紹一下子層傳父層的 $emit

我們直接用範例來解說好了~

這個範例要實現的功能是一個計數器,架構的部分會建立一個 component 裡面是一個 button,點擊時 count 會 +1 並傳到父層顯示。

首先第一件事就是先建立一個 component -> button-count 裡面有一個 button,然後我們在 component 裡面寫一個 increment 的 methods,在 button 上綁定 increment 的 click 事件,這將我們就能夠點擊的時候 count +1,到這邊應該都還很簡單,前面幾章都做過了。

但是這時候的 count 資料還是在 component 裡面,我們接下來要做的就是利用 $emit 將資料傳送至父層,首先我們要的是在點擊的時候同步將資料傳送至父層,所以我們就在 increment 裡面寫上一個 $emit 方法:

this.$emit('increment', this.count);
//第一個參數會是你要綁定的事件名稱
//第二個是你要透過這事件傳至父層的資料

接下來我們要在 component tag 上綁定剛剛在 component 內寫的 $emit 事件名稱,然後在父層寫一個 methods 讓 $emit 事件觸發的時候執行:

<button-count @increment="incrementTotal"></to-do-list>
//@increment 是 $emit 綁定的事件名稱
//incrementTotal 是父層的 methods

這邊要特別注意一點,$emit 事件的命名不能為大寫,所以能夠採用 kebab-case 命名。

如果使用大寫命名它會自動把它解析為小寫,這樣可能會出現命名不同的情況

<body>
  <div id="app">
    count: {{count}}<br>
    <button-count @increment="incrementTotal"></to-do-list>
    }
  </div>
</body>
<script>
  const vm = new Vue({
    el: '#app',
    data: {
      count: ''
    },
    methods: {
      incrementTotal(count) {
        this.count = count;     
        //觸發事件執行時會接收 component 傳來的資料,將它賦值給 data 並渲染
      }
    },
    components: {
      'button-count': {
        data() {
          return {
            count: 0
          }
        },
        template: `<button @click="increment">+1</button>`,
        methods: {
          increment() {
            this.count += 1;
            this.$emit('increment', this.count);
          }
        }
      }
    }
  })
</script>

結果就會是這樣囉~

$emit 大致上的流程就是這樣,接下來我們就將上一章的 To Do List 做完整吧,接下來要做的就是點擊 component 裡面的 remove button 能夠將該項目移除掉,那該怎麼做呢?!

先來看一下先前 remove 的 methods 怎麼寫

removeToDo(index) {
    this.todos.splice(index, 1)
}

但是我們現在 v-for 是在 component 裡面執行的,所以現在 index 是在 component 裡面,我們必須將他傳至父層,並把該項目移除。

下面我們就動手將 remove 的事件完成吧~

<body>
  <div id="app">
    <input type="text" v-model="newTodo">
    <button @click="addToDo">Add</button>
    <to-do-list :todos="todos" @removeIndex="removeToDo"></to-do-list>
  </div>
</body>
<script>
  const vm = new Vue({
    el: '#app',
    data: {
      newTodo: '',
      todos: []
    },
    methods: {
      addToDo() {
        this.todos.push(this.newTodo);
        this.newTodo = '';
      },
      removeToDo(index) {
        this.todos.splice(index, 1);
        //接到 index 後移除項目
      }
    },
    components: {
      'to-do-list': {
        props: ['todos'],
        template: `<ul>
          <li v-for="(todo, index) in todos">{{todo}}
            <button @click="getRemoveIndex(index)">Remove</button>
          </li>
        </ul>`,
        methods: {
          getRemoveIndex(index) {
            this.$emit('removeIndex', index)
            //將 index 透過 $emit 事件傳送
          }
        }
      }
    }
  })
</script>

這樣就都了解如何在子父層間傳值了呢~

接下來下一章會開始介紹在 Vue 裡面也很重要的生命週期囉~


上一篇
props
下一篇
Lifecycle
系列文
菜菜菜的 Vue 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言