vue.js 組件之間傳遞數據

前言
組件是 vue.js 最強大的功能之一,而組件實例的作用域是相互獨立的,這就意味著不同組件之間的數據無法相互引用。如何傳遞數據也成了組件的重要知識點之一。

組件
組件與組件之間,還存在著不同的關系。父子關系與兄弟關系(不是父子的都暫稱為兄弟吧)。

父子組件
父子關系即是組件 A 在它的模板中使用了組件 B,那么組件 A 就是父組件,組件 B 就是子組件。

// 注冊一個子組件
Vue.component('child', { 
     data: function(){
          text: '我是father的子組件!' 
     } ,
    template: '<span>{{ text }}</span>'})
// 注冊一個父組件
Vue.component('father', { 
     template: '<div><child></child></div>' 
// 在模板中使用了child組件
})

直接使用 father 組件的時候:
<div id="app"> <father></father></div>
頁面中就會渲染出 :我是father的子組件!
father 組件在模板中使用了 child 組件,所以它就是父組件,child 組件被使用,所以 child 組件就是子組件。

兄弟組件
兩個組件互不引用,則為兄弟組件。

Vue.component('brother1', { 
     template: '<div>我是大哥</div>'
})
Vue.component('brother2', {
     template: '<div>我是小弟</div>'
})

使用組件的時候:
<div id="app"> <brother1></brother1> <brother2></brother2></div>

頁面中就會渲染出 : 我是大哥 我是小弟

Prop
子組件想要使用父組件的數據,我們需要通過子組件的 props 選項來獲得父組件傳過來的數據。以下我使用在 .vue 文件中的格式來寫例子。
如何傳遞數據
在父組件 father.vue 中引用子組件 child.vue,把 name 的值傳給 child 組件。

<template> 
    <div class="app"> // message 定義在子組件的 props 中
         <child :message="name"></child> </div>
    </template>
<script> 
    import child from './child.vue';
    export default { 
        components: { child }, 
        data() { 
            return { 
                name: 'linxin' 
            } 
        }
 }
</script>

在子組件 child.vue 中的 props 選項中聲明它期待獲得的數據

<template>
       <span>Hello {{message}}</span>
</template>
<script> 
       export default { 
         // 在 props 中聲明獲取父組件的數據通過 message 傳過來 
       props:['message'] }
</script>

那么頁面中就會渲染出:Hello linxin

單向數據流
當父組件的 name 發生改變,子組件也會自動地更新視圖。但是在子組件中,我們不要去修改 prop。如果你必須要修改到這些數據,你可以使用以下方法:
方法一:把 prop 賦值給一個局部變量,然后需要修改的話就修改這個局部變量,而不影響 prop

export default { 
      data(){ 
          newMessage: null
       },
      props: ['message'], 
      created(){ 
            this.newMessage = this.message;
      }
}

方法二:在計算屬性中對 prop 進行處理

export default {
     props: ['message'],
     computed{ 
         newMessage(){ 
             return this.newMessage + ' 哈哈哈';
          }
     }
}

自定義事件
prop 是單向綁定的:當父組件的屬性變化時,將傳導給子組件,但是不會反過來。修改子組件的 prop 值,是不會傳回給父組件去更新視圖的。那么子組件要如何去與父組件通訊呢?
那就是自定義事件。通過在父組件 $on(eventName) 監聽自定義事件,當子組件里 $emit(eventName) 觸發該自定義事件的時候,父組件執行相應的操作。
比如在父組件中控制一個彈框子組件的顯示,在子組件中按下關閉之后,告訴父組件去隱藏它,然后父組件就執行操作隱藏彈框。

<template>
     <div class="app"> 
// hide 為自定義事件,名字可以自己隨便起,不能有大寫字母,可以使用短橫線 
// @hide 監聽子組件觸發 hide 事件,則會執行 hideDialog 方法
         <dialog :is-show="show" @hide="hideDialog"></dialog> 
         <button @click="showDialog">顯示彈框</button>
     </div>
</template>
<script> 
        import dialog from './dialog.vue'; 
        export default { 
            components: { dialog },
            data() { 
                   return {
                       show: false
                   } 
             }, 
            methods: {
                showDialog() { 
                     this.show = true;
                 }, 
                hideDialog() { 
                     this.show = false; 
                }
          }
 }
</script>

在子組件 dialog.vue 中:

<template>
    <div class="dialog" v-show="isShow"> 
          <p>這里是彈框子組件</p> 
          <button @click="toHide">關閉彈框</button> 
    </div>
</template>
<script> 
    export default {
          // 駝峰式命名的 prop 需要轉換為相對應的短橫線隔開式 is-show  
          props: ['isShow'],
          methods: { 
               toHide(){
                    // $emit 方法觸發父組件的監聽事件
                   this.$emit('hide');
                } 
          }
}
</script>

這樣就實現了父子組件之間的相互通訊。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容