2019年6月17日 星期一

初探Vue.js的emit

初探Vue.js的emit

前言

  最近用Vue.js的時候需要在Child component取得Parent component,但查了一下發現Vue.js不允許取得Parent component,要透過emit來溝通,在此把學習過程做個紀錄。

內容

  由於第一次使用emit在treeview,所以範例會像treeview,範例如下
html的部分
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<div id="app">
  <parent :nodelist="nodelist"></parent>
</div>
</body>
</html>

javascript的部分
Vue.component('child',{
  props:['node'],
  template:[
    '<ul>\n',
    '  {{node.name}}<input type="button" value="emit" @click="onClick">\n',
    '  <child v-for="childnode in node.childNodeList" :node="childnode" @evt-emit="onEmit"></child>\n',
    '</ul>\n',
  ].join(''),
  methods:{
    onClick:function(){
      this.$emit('evt-emit',this.node);
    },
    onEmit:function(node){
      console.log("recv emit node:"+node.name+" recv node:"+this.node.name);
      //emit to parent
      this.$emit('evt-emit',node)
    }
  }
});
//
Vue.component('parent',{
  props:['nodelist'],
  template:[
    '<div><child v-for="node in nodelist" :node="node" @evt-emit="onEmit"></child></div>'
  ].join(''),
  methods:{
    onEmit:function(node){
      console.log('recv by parent component');
    }
  }
  
});
let ctrlObj = new Vue({
  el:"#app",
  data:function(){
    return {
      nodelist:[
        {
          name:'node1',
          childNodeList:[
            {
              name:'node3',
              childNodeList:[
                {
                  name:'node4',
                  childNodeList:[]
                }
              ]
            }
          ]
        },
        {
          name:'node2',
          childNodeList:[]
        }
      ]
    };
  }
});
整體的component關係如下圖
Component的關係圖
執行畫面
範例的執行畫面

範例會在Child component的按鍵click使用emit,emit有點類似發送事件,但要注意第一個變數是一個字串(範例為"evt-emit"),這個變數"不能用任何的大寫"!第一用時在這點上卡了不少的時間,第2個變數就可以自己選擇要傳送的資料來傳入,範例會傳入node的資料。emit後事如何接收的呢?在component的template裡可以看到"@evt-emit="onEmit"","evt-emit"就是第一個參數的名稱,後方可填上method來接收,範例的接收為"onEmit",在Child component裡的"onEmit"可以看到顯示資訊後又再一次執行emit,這個步驟是為了可以傳到最上層的component,如果不執行的話,emit只會傳給上一層的component而已,如範例中在node4執行emit且不再執行emit的話,就只剩下node3可以接收到,要注意emit一次只能傳一層!範例也在Parent component裡接收emit事件,做法一樣,但 "onEmit"沒有再次emit,所以"ctrlObj"是無法接收的。

參考資料

Components Basics
[Vue.js] 父子組件溝通 - $emit / $on

沒有留言:

張貼留言