2019年1月23日 星期三

[Vue.js] 父子元件的雙向溝通,簡單的props和emit使用範例


第一部分、利用props將資料傳給components使用 (父元件→子元件)
1. 子元件的設定
首先有一個子元件(child component),我們設定一個propsuserName,型態為String,如果data內的參數,你可以直接在模板裡用{{ userName }}印出,或在function內以this.userName來進行操作。
template的內容是以顯示userName在一個HTML的輸入框裡
// Child Component
Vue.component("child-input", {
  template: `
    <div>
      <label>Name</label>
      <input v-model="childUserName" type="text"/>
    </div>
  `,
  props: {
    // camelCase in JavaScript
    userName: String
  },
  data: function() {
    return {
      childUserName: this.userName
    };
  }
});
※Vue會警告你盡量不要直接修改props參數的值,因此我們設定了childUserName來避免這個問題。
警告內容:
"Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value."

2. 父元件的設定
在HTML裡要用user-name來傳值,也就是說component的命名法遵循camelCase,到HTML內時則是用kebab-case來識別。
user-name和:user-name兩者的用法不同,如果是user-name="initial_input",會把"initial_input"當成字串傳過去,如果前面加上冒號「:」變成:user-name="inital_input",則是把inital_input這個參數的值傳過去。
// HTML
<div id="app">
  <!-- kebab-case in HTML -->
  <child-input :user-name="initial_input"></child-input>
</div>
// JS
new Vue({
  el: "#app",
  data: function() {
    return {
      initial_input: "Annie",
    };
  }
});




第二部分、利用emit將components的資料回傳 (子元件→父元件)
1. 子元件的設定
延續第一部分,我們在methods內新增一個sendToParent的function,@input="sendToParent"代表我們觸發的時機。
看一下sendToParent內容,$emit後面第一個參數"update-text",代表設定一個update-text的事件,第二參數是同時把childUserName這個參數傳出去,如果需要傳更多的參數,直接用逗號分隔接在後面。
Vue.component("child-input", {
  template: `
    <div class="form-group mt-3">
      <label>Name</label>
      <input v-model="childUserName" @input="sendToParent" type="text"/>
    </div>
  `,
  props: {
    userName: String
  },
  data: function() {
    return {
      childUserName: this.userName
    };
  },
  methods: {
    sendToParent: function() {
      this.$emit("update-text", this.childUserName);
    }
  }
});

2. 父元件的設定
父元件的部分也新增一個getChildText的function來接收子元件的資料,當子元件觸發'update-text'時,就會執行getChildText來接收傳送的值,value就是從子元件傳來的childUserName。如果傳多個值,記得在這邊填相應數量的參數來接收。
// JS
new Vue({
  el: "#app",
  data: function() {
    return {
      initial_input: "Annie",
    };
  },
  methods: {
    getChildText: function(value) {
      this.initial_input = value;
    }
  }
});
// HTML
<div id="app">
  <child-input :user-name="initial_input" 
               @update-text="getChildText"></child-input>
</div>


完整的程式碼請參考codepen上的範例:

See the Pen
Sending Messages between Parent and Child
by chenuin (@chenuin)
on CodePen.



相關文章:

沒有留言:

張貼留言