文章出處

前面的話

  父組件使用props傳遞數據給子組件,子組件怎么跟父組件通信呢?這時,Vue的自定義事件就派上用場了。本文將詳細介紹Vue自定義事件

 

事件綁定

  每個 Vue 實例都實現了事件接口 (Events interface),即

使用 $on(eventName) 監聽事件
使用 $emit(eventName) 觸發事件

  [注意]Vue 的事件系統分離自瀏覽器的EventTarget API。盡管它們的運行類似,但是 $on$emit 不是addEventListenerdispatchEvent 的別名

  另外,父組件可以在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件

  [注意]不能用 $on 偵聽子組件拋出的事件,而必須在模板里直接用 v-on 綁定

<div id="example">
  <parent></parent>
</div>
<script>
var childNode = {
  template: `<button @click="incrementCounter">{{ counter }}</button>`,
  data(){
    return {
      counter: 0
    }
  },
  methods:{
    incrementCounter(){
      this.counter ++;
      this.$emit('increment');
    }
  },
}
var parentNode = {
  template: `
  <div class="parent">
    <p>{{total}}</p>
    <child @increment="incrementTotal"></child>
    <child @increment="incrementTotal"></child>
  </div>
  `,
  components: {
    'child': childNode
  },
  data(){
    return {
      'total':0
    }
  },
  methods:{
    incrementTotal(){
      this.total ++;
    }
  }
};
// 創建根實例
new Vue({
  el: '#example',
  components: {
    'parent': parentNode
  }
})
</script>

 

命名約定

  自定義事件的命名約定與組件注冊props的命名約定都不相同,由于自定義事件實質上也是屬于HTML的屬性,所以其在HTML模板中,最好使用中劃線形式

<child @pass-data="getData"></child>

  而子組件中觸發事件時,同樣使用中劃線形式

 this.$emit('pass-data',this.childMsg)

 

數據傳遞

  子組件通過$emit可以觸發事件,第一個參數為要觸發的事件,第二個事件為要傳遞的數據

this.$emit('pass-data',this.childMsg)

  父組件通過$on監聽事件,事件處理函數的參數則為接收的數據

    getData(value){
      this.msg = value;
    }
<div id="example">
  <parent></parent>
</div>
<script>
var childNode = {
  template: `
  <div class="child">
    <div>
      <span>子組件數據</span>
      <input v-model="childMsg" @input="data">
    </div>
    <p>{{childMsg}}</p>
  </div>
  `,
  data(){
    return{
      childMsg:''
    }
  },
  methods:{
    data(){
      this.$emit('pass-data',this.childMsg)
    }
  }
}
var parentNode = {
  template: `
  <div class="parent">
    <div>
      <span>父組件數據</span>
      <input v-model="msg">
    </div>
    <p>{{msg}}</p>
    <child @pass-data="getData"></child>
  </div>
  `,
  components: {
    'child': childNode
  },
  data(){
    return {
      'msg':'match'
    }
  },
  methods:{
    getData(value){
      this.msg = value;
    }
  }
};
// 創建根實例
new Vue({
  el: '#example',
  components: {
    'parent': parentNode
  }
})
</script>

  下面示例中,修改子組件中的input值,則父組件到接收到相同值,則顯示出來

 

sync修飾符

  在一些情況下,可能會需要對一個 prop 進行雙向綁定。事實上,這正是Vue1.x中的 .sync修飾符所提供的功能。當一個子組件改變了一個 prop 的值時,這個變化也會同步到父組件中所綁定的值。這很方便,但也會導致問題,因為它破壞了單向數據流的假設。由于子組件改變 prop 的代碼和普通的狀態改動代碼毫無區別,當光看子組件的代碼時,完全不知道它何時悄悄地改變了父組件的狀態。這在 debug 復雜結構的應用時會帶來很高的維護成本,上面所說的正是在 2.0 中移除 .sync 的理由

  從 2.3.0 起重新引入了 .sync 修飾符,但是這次它只是作為一個編譯時的語法糖存在。它會被擴展為一個自動更新父組件屬性的 v-on 偵聽器

<comp :foo.sync="bar"></comp>

  會被擴展為:

<comp :foo="bar" @update:foo="val => bar = val"></comp>

  當子組件需要更新 foo 的值時,它需要顯式地觸發一個更新事件:

this.$emit('update:foo', newValue)

  因此,可以使用.sync來簡化自定義事件的操作,實現子組件向父組件的數據傳遞

<div id="example">
  <parent></parent>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
var childNode = {
  template: `
  <div class="child">
    <div>子組件數據:{{childMsg}}</div>
    <input v-model="childMsg">
    <button @click=add >+1</button>
  </div>
  `,
  data(){
    return{
      childMsg: 0
    }
  },
  methods:{
    add(){
      this.childMsg++;
      this.$emit('update:foo',this.childMsg);
    }
  }
};
var parentNode = {
  template: `
  <div class="parent">
    <p>父組件數據:{{msg}}</p>
    <child :foo.sync="msg"></child>
  </div>
  `,
  components: {
    'child': childNode
  },
  data(){
    return {
      'msg':0
    }
  }
};
// 創建根實例
new Vue({
  el: '#example',
  components: {
    'parent': parentNode
  }
})
</script>

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()