vue 組件之間的通信(父子組件,vuex)

vue組要思想之一就是組件式開發,那麼組件和組件之間通信也就是很重要的一個點。

組件間的關係包括: 父子關係、 兄弟關係、隔代關係
1.父子組件傳值問題
通過props父組件可以直接的給子組件傳值,每一次父組件更新時,子組件的props會刷新成最新值。

(1)子組件中調用父組件中的方法 && 子組件向父組件傳值
例如:子組件中修改了參數在需要調用父組件重的刷新頁面獲取數據的方法:
父組件中的刷新方法名
在這裏插入圖片描述
給父組件中引用的子組件上通過v-on(@)綁定gitDictClassify事件,來監聽子組件的觸發事件
在這裏插入圖片描述在子組件中通過this.$emit(’ xxx ')觸發父組件註冊的事件來處理數據邏輯
在這裏插入圖片描述(2)子組件向父組件傳參

子組件中
this.$emit(‘方法名’,數據)
在這裏插入圖片描述

父組件中綁定子組件中的定義的方法

在這裏插入圖片描述

2. $attrs 和 $listeners

作用: (父)A——>B——>C 直接讓A組件傳消息給C組件

3. EventBus 中央事件總線

EventBus是安卓 發佈/訂閱事件總線的優化。
優點:簡化組件間通信問題
EventBus 3.0版本後,開發者能夠自定義訂閱方法的名字,而沒必要規定以“onEventXX”開頭的方法了
任意組件之間通信,在項目規模不大的情況下,可以使用EventBus方式 ,中大型項目,使用vuex狀態管理。

使用EventBus的方法:
(1)新建一個Vue的bus對象.
通過建立一個eventBus.js文件,暴露一個空的Vue實例

import Vue from 'vue'
export defalut new Vue()

在需要通信的兩個組件中分別引入eventBus文件
import bus from ‘common/utils/eventBus’

(2)然後通過$emit觸發(提交)事件,

頁面A
 bus.$emit('eventBusName', 'data')  //data包含數據和參數

(3)$on監聽事件
例如:頁面B中 created時接收數據

created(){
  bus.$on('eventBusName', this.handleData)
},

methods:{
  handleData() {}
}

存在問題:
1.第一次觸發的時候組件B中的on事件沒有被觸發,2.且第二次以後觸發時,事件觸發執行越來越多

原因&&解決:
1.當我們在A頁面時,頁面B還沒生成, B中created監聽的事件還沒有被觸發,這時候B是監聽不到的。(生命週期)。
解決:將A頁面的emit事件寫在beforeDestory中去,這個時候,B組件已經被Created了,所以這樣能觸發$on 事件。

A頁面
beforeDestroy () {
 bus.$emit('get', data)
},

2.由於on事件是不會自動清除銷燬的,所以每一次調用,前一個一直在,就導致了累加,故需要我們手動銷燬。
解決: 在B組件頁面添加bus.$off來關閉on對應的事件

B頁面
beforeDestroy () {
  bus.$off('get', this.handleData)
}

總結: 所以,如果想要用bus 來進行頁面組件之間的數據傳遞,需要注意
組件A 的emit事件應在beforeDestory生命週期內。
組件B內的$on記得要用off銷燬。

4. vuex狀態管理
首先通過npm安裝:npm install vuex --save

vuex進行組件間通信的核心思路就是將vuex作爲一個store,將子組件的數據都存進去,子組件再從vuex裏面獲取數據,數據改變時再通過commit提交到store裏。

通過store.state來獲取狀態對象
通過store.commit方法來觸發狀態更新

查看簡單用法點擊這裏

在這裏插入圖片描述
 
Vuex有五個屬性:State、Getter、Mutation、Action、Module。

組件不允許直接修改屬於 store 實例的 state,而應執行 action 來分發 (dispatch) 事件通知 store 去改變

  1. State裏放入的是倉庫的數據,類似於js裏的data
  //Vuex裏的數據需要從計算屬性(computed)裏讀取
  import { mapState ,mapMutations} from 'vuex'
  export default {
    compoted:{
        ...mapState(['name'])
    },
  }

2.getters 爲組件提供經處理的數據源,比如: 把原變量名簡化,轉化數據類型等

 getter: {
     token: state => state.user.token
 }
  1. Mutations 是更改state裏的數據的的唯一標準方式(同步),
    mutation中式存放處理數據的方法的集合。使用時需要commit(同步函數)。
    即修改state裏的數據只能用mutations裏面的方法,這些方法是同步
    你可以在組件中使用 this.$store.commit(‘xxx’) 提交 mutation,或者使用 mapMutations 輔助函數將組件中的 methods 映射爲 store.commit
//  js 中mutations的方法
const mutations = {
  SET_TOKEN: (state, token) => {
    state.token = token
    setToken(token)
  },
}

4.Actions:組件通過actions提交mutation(異步)
actions可以理解爲通過將mutations裏面處裏數據的方法變成可異步的處理數據的方法。
分發 Action通過store.disoatch方法觸發。
store.dispatch(‘handleLogin’)

js
const actions = {
  // 使用 ticket 登錄
  handleLogin({ commit }, ticket) {
    return new Promise((resolve, reject) => {
      login(ticket).then(res => {
        // 設置 token
        commit('SET_TOKEN', res.data.ticket)
        resolve()
      }).catch(err => {
        reject(err)
      })
    })
  },


頁面中需要用
import { mapActions } from 'vuex'
methods: {
    ...mapActions(['handleLogin'])
}

補充:javascript中的奇怪的問題
console.log(0.1 + 0.2);
console.log(0.1 + 0.2 == 0.3);
一個稍微有點編程基礎的回答是:“你不能確定。可能會輸出“0.3”和“true”,也可能不會。
所以我們又測試了幾個例子發現能夠得處按照正常的數學運算的結果。
乍一看是不是覺得很神奇?
原因是:JavaScript中的數字和浮點精度的處理相同,因此,可能不會總是產生預期的結果。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章