天天看點

bufferedreader接收不到資料_Vue資料傳遞--教你特殊的實作技巧

最近碰到了比較多的關于vue的eventBus的問題,之前定技術選型的時候也被問到了,vuex和eventBus的使用範圍。是以簡單的寫一下。同時有一種特殊的實作方案。 有這麼幾種資料傳遞方式,vuex、props、eventBus和特殊的eventBus。

bufferedreader接收不到資料_Vue資料傳遞--教你特殊的實作技巧
vuex

不介紹,資料量和複雜度達不到不用它你才會向下看。

props

*demo*

父子元件傳值,官方api,隻寫個demo。

1.父元件
<son :info="info" @update="updateHandler"/>
// data
info: 'sendToSon'
// methods
updateHandler (newVal) {
 this.info = newVal
}           
2.子元件
// props
props: ['info']
// 向上傳值,某個方法中使用
this.$emit('update', 'got')           

父向子傳值-->props 子向父傳值-->子元件綁定事件回調定義在父元件,子元件觸發此事件。 因不推薦子元件内直接修改父元件傳入的props,需使用自定義事件。 限制 父子元件。 eventBus demo bus皆為導入的bus執行個體

// bus
const bus = new Vue()
// 資料接收元件
// 目前元件接收值則
bus.$on('event1', (val)=>{})
// 資料發出元件
// 目前元件發出值則
bus.$emit('event1', val)
//           

可以看出本質是一個vue執行個體充當事件綁定的媒介。 在所有執行個體中使用其進行資料的通信。 雙(多)方使用同名事件進行溝通。

問題

$emit

時,必須已經

$on

,否則将無法監聽到事件,也就是說對元件是有一定的同時存在的要求的。(注:路由切換時,新路由元件先 created,舊路由元件再destoryed,部分情況可以分别寫入這兩個生命周期,見此問題)。

$on

在元件銷毀後不會自動解除綁定,若同一元件多次生成則會多次綁定事件,則會一次

$emit

,多次響應,需額外處理。 資料非“長效”資料,無法儲存,隻在

$emit

後生效。 是以是否有一種更适用的方案呢? 特殊的eventBus?

demo

我們先來看個代碼,線上代碼。 bus皆為導入的bus執行個體。

// bus
const bus = new Vue({
 data () {
  return {
   // 定義資料
   val1: ''
  }//
 },
 created () {
  // 綁定監聽
  this.$on('updateData1', (val)=>{
   this.val1 = val
  })
 }
})
// 資料發出元件
import bus from 'xx/bus'
// 觸發在bus中已經綁定好的事件
bus.$emit('update1', '123')
// 資料接收元件

{{val1}}
// 使用computed接收資料
computed () {
 val1 () {
  // 依賴并傳回bus中的val1
  return bus.val1
 }
}//           
  • 不同 正統的eventBus隻是用來綁定和觸發事件,并不關心資料,不與資料發生交集。而這個方案多一步将資料直接添加在bus執行個體上。且事件監聽與資料添加需提前定義好。 資料接收方不再使用

    $on

    來得知資料變化,而是通過計算屬性的特征被動接收。 解決的問題 通信元件需同時存在?資料在bus上存儲,是以沒有要求。 多次綁定?綁定監聽都在bus上,不會重複綁定。 資料隻在$emit後可用?使用計算屬性直接讀取存在bus上的值,不需要再次觸發事件。
  • 探讨 為什麼使用計算屬性 其實應該是為什麼不能直接添加到data上,如 data1: bus.data1?我們可以再看一段代碼,線上代碼。 将bus修改為
data () {
 return {
  // 多一層結構
  val: {
   result: 0
  }//
 }
},
created () {
 this.$on('update1', val => {
  console.log('觸發1', i1++)
  this.val.result = val
 })
}           

資料接收元件改為

// template
data中擷取直接修改值:{{dataResult}}
data中擷取直接修改值的父層:{{dataVal}}
computed中依賴直接修改值:{{computedResult}}
// js//
data () {
  return {
   // 擷取直接修改值
   dataResult: bus.val.result,
   // 擷取直接修改值的父層
   dataVal: bus.val
  }
 },
 computed: {
  computedResult () {
   // 依賴直接修改值
   return bus.val.result
  }
 }//           

可以看到,data中擷取直接修改值值的資料是無法動态響應的。

為什麼要用事件

其實不用

$emit

觸發,使用 bus.val = 1直接指派也是可以的,那麼為什麼不這麼做呢? 簡化版的vuex 其實這種eventBus就是簡化版的vuex。 vue文檔中有這樣一段話: 元件不允許直接修改屬于 store 執行個體的 state,而應執行 action 來分發 (

dispatch

) 事件通知 store 去改變,我們最終達成了 Flux 架構。這樣約定的好處是,我們能夠記錄所有 store 中發生的 state 改變。 store對應 bus執行個體,

state對應 data

action

對應 事件, dispatch對應

$emit

。 同時vuex中元件擷取資料的方式正是通過計算屬性,那麼其實vuex和Flux架構的了解和使用也沒有那麼難不是嗎。

結語

感謝您的觀看,如有不足之處,歡迎批評指正。

解析Vue-router相關幹貨及工作原理​www.jianshu.com

bufferedreader接收不到資料_Vue資料傳遞--教你特殊的實作技巧

CSS 布局經典問題大全​www.jianshu.com

bufferedreader接收不到資料_Vue資料傳遞--教你特殊的實作技巧

繼續閱讀