Custom Event 客製化事件

2020-10-05 component組件元件emitvmodel傳子傳父

# 命名事件(傳父 $emit)

如果組件想要修改資料,只能透過事件 來驅動父層(資料源)來修改,不可以直接由組件修改! 單向資料流

# 範列

# 使用方式

組件

組件 props 接收 父層 的資料, 如果要修改資料的話,要在事件上使用 $emit this.$emit(父層監聽的事件名稱, 參數)



















 





<template>
  <div>
    <p>{{ msg }}</p>
    <button @click="changeText">修改文字</button>
  </div>
</template>

<script>
export default {
  props: {
    msg: {
      type: String,
      requied: true,
    },
  },

  methods: {
    changeText() {
      this.$emit('change-text', 'From component text')
    },
  },
}
</script>

父層

屬性上接收子層 打過來的事件,使用 @監聽事件名稱="父層執行的事件" 再利用本地的事件,來修改資料!


 









 
 
 




<template>
  <CustomEvent :msg="message" @change-text="change" />
</template>

<script>
export default {
  data: () => ({
    message: 'From App text',
  }),

  methods: {
    change(text) {
      this.message = text
    },
  },
}
</script>

只能從資料的來源,來修改資料,不可以接收資料的組件修改。


# 雙向綁定 v-model

除了可以使用 $emit 讓子層傳遞事件來修改父層的資料外,也可以使用 v-model 來讓 子層父層 同步資料!

同時,你也不需要像一般的 $emit 要在 父層 綁定欲接收的事件屬性

# 範例

# 使用方式

父層

  • 將資料以 v-model 綁至組件 (傳遞至組件內部)




     
     












     




    <template>
      <div id="app">
        <p>父層的資料: {{ name }}</p>
        <!-- 使用 v-model 綁定資料 -->
        <CustomEvent v-model="name" />
      </div>
    </template>
    
    <script>
    import CustomEvent from './components/CustomEvent'
    
    export default {
      name: 'App',
      components: {
        CustomEvent,
      },
      data: () => ({
        name: 'naiky',
      }),
    }
    </script>
    

子層 CustomEvent.vue

  • model 參數接下 父層 傳遞的資料

    • prop 定義在 組件 中,資料的變數名稱
    • event 定義欲修改 父層 資料的事件名稱 (只能用 kebab-case 命名)
  • props 定義此 prop 資料的資料格式

    • 索引為 變數名稱
  • 雙向綁定 this.$emit(事件名稱, 傳送資料) 傳送資料 將會直接替換 父層 的資源























     
     
     


     
     
     

     
     
     
     




    <template>
      <div class="event">
        <div>
          使用者名稱:
          <h4>{{ name }}</h4>
        </div>
        <input
          placeholder="輸入想要修改父層的資料"
          @keypress.enter="submit"
          type="text"
          v-model="newName"
        />
        <button @click="submit">修改</button>
      </div>
    </template>
    
    <script>
    export default {
      data: () => ({
        newName: '',
      }),
      // ------------- 宣告綁定變數與綁定事件
      model: {
        prop: 'name',
        event: 'edit-name',
      },
      // ------------- 資料格式
      props: {
        name: String,
      },
      // ------------- 執行綁定事件
      methods: {
        submit() {
          this.$emit('edit-name', this.newName)
        },
      },
    }
    </script>
    

注意

就算在 model 已經宣告資料的變數,仍需要在 props 宣告資料的格式! 這是必須的!

# 雙向綁定 .sync

v-model 可以雙向綁定一個 prop,而 .sync 是可以同是綁定多個資料!

  • 父層 屬性傳遞資料時,加上 .sync

    <text-document v-bind:title.sync="doc.title"></text-document>
    
  • 子層 事件名稱使用 $emit(update:資料名稱, 新資料)

    this.$emit('update:title', newTitle)
    

注意

在使用.sync的時候,只能是一個變數,不能再經過運算!

v-bind:title.sync=”doc.title + ‘!’” 這樣是會失效的!

Last Updated: 10/6/2020, 1:21:51 PM