vue組件之間的數據傳遞方法

1.props屬性:

在父組件中,能夠經過子組件標籤屬性的形式將數據或者函數傳給子組件,子組件經過props去讀取父組件傳過來的數據vue

  • 用法vuex

    • 父組件傳數據給子組件:bash

      • 通常的屬性值都是用來給子組件展現的app

    • 子組件傳數據給父組件異步

      • 屬性值爲函數類型的,通常是用來子組件向父組件傳遞數據,子組件經過調用父組件傳過來的函數,能夠修改父組件的狀態數據函數

  • 缺點:工具

    • 隔層組件間傳遞: 必須逐層傳遞(麻煩)優化

    • 兄弟組件間: 必須藉助父組件(麻煩)ui

  • 注意:this

//子組件獲取父組件傳過來的值
props: {
    obj: {//obj爲{id:'2'}
       type: Object
     }
}複製代碼

引用類型的props,咱們能夠在子組件中直接修改引用類型屬性的值(如:this.obj.id='3',會生效),可是不能直接改變引用類型存儲的地址值(如:this.obj = {id: '3'}),會發出警告。

雖然子組件能夠直接修改父組件的狀態值,但咱們不建議這樣作,咱們但願全部的 prop 都使得其父子 prop 之間造成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,可是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態,從而致使你的應用的數據流向難以理解。

髒數據問題:如v-model是實現了雙向綁定,經過v-model更改數據,會更改父組件的數據,致使髒數據

解決方法:

利用計算屬性的set和get,在set中需實現子組件調用父組件的方法,確保數據流向是單向的

computed:{
    msg: {
        get(){
            return this.data
        },
        set(){
            this.$emit('EventName', this.data)
        }    
}}複製代碼

2.vue自定義事件:

  • 方式1: 給子組件標籤綁定事件監聽

    • 子組件向父組件的通訊方式

      • 功能相似於function props

      • 經過在父組件中給子組件標籤綁定自定義事件的監聽,再由子組件觸發事件,實現子組件向父組件傳遞數據的方法,事件名必須一致,且不能有大寫字母,v-on 事件監聽器在 DOM 模板中會被自動轉換爲全小寫 (由於 HTML 是大小寫不敏感的)

        // 方式一: 經過v-on綁定
        <component @delete_todo="deleteTodo"/>
        // 方式二: 經過$on()綁定
        this.$refs.xxx.$on('delete_todo', function (todo) {
        this.deleteTodo(todo)})​
        經過this.$emit('delete_todo', todo)觸發事件複製代碼
    • 不適合隔層組件和兄弟組件間的通訊

    • 注意:

      • 在組件標籤上綁定事件,會被解析爲vue自定義事件

      • 在普通的標籤上綁定事件,會被解析爲DOM事件

        <--!     
        表示在組件component綁定了一個名爲click的vue自定義事件,
        至關於作了vm.$on('click',fn)    
        注意:不是常規理解的點擊事件,這裏與點擊無關,只是名字恰好是click,
        固然實際操做中不建議取這類特殊的名字 
        -->
        <component @click="fn"/>
        <--! 表示在div上綁定一個click的點擊事件,是DOM事件 -->​
        ​<div @click="fn"/>複製代碼

  • 方式2: 經過單獨的vm對象綁定監聽/分發事件

    • 任意組件間通訊(相似於pubsub)

      • 建立一個公用的vm對象

      import Vue from 'vue'export default new Vue()複製代碼
      • 在接收消息的組件,綁定監聽

      import vm from './vm.js'mounted(){
          vm.$on('delete_todo', function (todo) {
              this.deleteTodo(todo)
          })}複製代碼
      • 在發送消息的組件,觸發事件

      vm.$emit('delete_todo', todo)複製代碼
    • 事件總線(EventBus),其實跟上面的用法同樣,這裏是把vm實例綁在了Vue的顯示原型上

      //點擊任意一個組件,其餘組件的值跟着變化,利用總線去實現兄弟之間的通訊
      Vue.prototype.bus = new Vue()
      var vm = new Vue({
          el:"#app"
          })    
      //v-a組件
      Vue.component('v-a', {
          template:'<div @click="handle">{{msg}}</div>',
          data(){
              return {
                  msg: 'v-a'
              }
          },
          mounted () {
              //綁定事件監聽
              this.bus.$on('bus',(msg)=>{
                  this.msg = msg
              })
          },
          methods: {
              handle () {
                  //觸發事件
                  this.bus.$emit('bus', this.msg)
              }
          }})
      //v-b組件
      Vue.component('v-b', {
          template:'<div @click="handle">{{msg}}</div>',
          data(){
              return {
                  msg: 'v-b' 
             }
          },
          mounted () {
              //綁定事件監聽
              this.bus.$on('bus',(msg)=>{
                  this.msg = msg
              })
          }, 
         methods: {
              handle () {
                  //觸發事件 
                 this.bus.$emit('bus', this.msg)
              }
          }})複製代碼

3.消息的訂閱和發佈(pubsub)

  • 適用於任何關係的組件間的通訊

  • 缺點:相對於vuex,管理不夠集中

  • 用法:

    • 引入pubsub-js庫

    • 在接收消息的組件訂閱消息(subscribe)

      PubSub.subscribe('name',(name,data)=>{})複製代碼
    • 在發送消息的組件發佈消息 ( publish)

      PubSub.publish('name',data)複製代碼
  • 其餘用法能夠參考官方API文檔,這裏不細說

4.vuex

vuex是專門爲vue.js應用程序定義的狀態管理模式,當多個組件須要共享數據時,咱們通常用vuex去管理狀態數據,實現多個組件間的相互通訊


vuex的核心

  • state:存放數據

  • mutations:修改數據

  • actions:提交mutation,修改數據

  • getters:存放數據,相似於vue的計算屬性

知道了這幾個核心概念後,咱們還須要知道怎麼合理使用他們

  • 如何從倉庫store讀取數據

    • state

      從store的實例中咱們能夠經過store.state去得到狀態數據,爲了使得store能夠全局使用,咱們須要經過Vue.use(Vuex),將vuex注給全部vue子的組件,Vue.use回去調用插件的install方法,將stroe綁到Vue.prototype,這樣Vue的實例對象都能經過vm.store獲取或操做倉庫的數據組件內經過this.$store.state能夠得到

      state:{    
       data: 0
      }複製代碼

    • getters

      有些狀態熟悉須要根據其餘狀態屬性計算而動態得到,通常都是存在getters中,組件經過調用this.$store.getters

      Getter 接受 state 做爲其第一個參數

      getters:{
          data2(state){
              return state.data+1
          }
      }複製代碼

  • 如何修改倉庫store的數據

    • mutations(同步修改)

      更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation,接受 state 做爲第一個參數 ,mutation接收提交載荷,第二個參數爲載荷,在大多數狀況下,載荷應該是一個對象 ,這樣能夠接收多個數據

      mutations:{
          mutationType:(state,data)=>{
              state.data = data
          }
      }複製代碼
    • actions(異步修改)

      在action中提交mutation,組件經過store.dispatch觸發action

      由於vue的調試工具沒法檢測到mutations的異步變化,因此咱們若是須要異步修改狀態數據,通常是放在action去異步獲取到數據後再提交mutation,確保vue的調試工具能夠檢測到,mutation的變化

  • 注意點

    當組件須要給vue中的狀態數據添加屬性時,經過obj.的形式沒法實現

    由於Vuex 的 store 中的狀態是響應式的,那麼當咱們變動狀態時,監視狀態的 Vue 組件也會自動更新。這也意味着 Vuex 中的 mutation 也須要與使用 Vue 同樣遵照一些注意事項:

    1. 咱們最好提早在 store 中初始化好全部所需屬性。

    2. 當須要在對象上添加新屬性時,咱們應該

    • 使用 Vue.set(obj, 'newProp', 123), 或者

    • 以新對象替換老對象。例如,利用 stage-3 的對象展開運算符,咱們能夠這樣寫:

    state.obj = { ...state.obj, newProp: 123 }複製代碼
  • 優化

    • import {mapState,mapGetters,mapMutations,mapActions} from "vuex";使得在使用vuex時,組件能夠寫的更加的簡潔

    • 數據比較多的時候,使用module

    • 使用常量存放mutation_type

優勢:

  • 多組件共享狀態(數據的管理)

  • 組件間的關係也沒有限制

  • 功能比pubsub強大, 更適用於vue項目

5.slot插槽

  • 父向子通訊

  • 通訊是帶數據的標籤

  • 注意: 標籤是在父組件中解析

相關文章
相關標籤/搜索