基于注入的一種狀態(tài)管理的思路

開始嘗試做自己的狀態(tài)管理缔逛。

上文說了页响,我們可以定義一個 reactive 結(jié)構(gòu)的userOnline 闺魏,然后注入到根組件里面矾柜,那么相關(guān)的處理函數(shù)要怎么辦呢阱驾?

我么可以寫一個單獨(dú)的js文件,然后用import的方式引入進(jìn)來怪蔑,然后我們就可以做統(tǒng)一的處理了里覆。

js文件如下:


import { provide, inject, reactive, readonly } from 'vue'
import sysUserInfo from './symbol'

const userState = () => {
  // 定義標(biāo)識
  // const sysUserInfo = Symbol('userOnlineInfo')

  // 存放當(dāng)前登錄的用戶信息
  const userInfo = reactive({
    isLogon: false,
    isOnline: false,
    userId: 1,
    userCode: 'jyk',
    userNike: '海洋',
    departmentId: 123,
    departmentName: '',
    role: [1],
    power: [1, 2, 3]
  })

  // 在當(dāng)前組件里面注入
  const register = () => {
    provide(sysUserInfo, userInfo)
  }

  // 獲取共享的用戶狀態(tài)
  const _user = inject(sysUserInfo)

  // 設(shè)置登錄用戶的信息
  const setUser = (user) => {
    Object.assign(_user, user)
  }

  // 返回注入的狀態(tài),只讀形式
  const getUser = () => {
    return readonly(_user)
  }

  // 返回當(dāng)前用戶是否登錄
  const isLogon = () => {
    return _user.isLogon
  }

  return {
    // 返回組件內(nèi)狀態(tài)
    userInfo: readonly(userInfo),
    // 在組件里注入狀態(tài)缆瓣,可以實現(xiàn)子組件共享
    register,
    // 修改狀態(tài)的函數(shù)
    setUser,
    // 獲取共享的狀態(tài)
    getUser,
    // 返回是否登錄的狀態(tài)
    isLogon
  }
}

export default userState

定義一個 reactive的 userInfo喧枷,實現(xiàn)響應(yīng)式

在函數(shù)內(nèi)部定義 userInfo,然后在return的時候加上readonly作為限制,這樣可以就以避免誤操作而導(dǎo)致直接改變狀態(tài)隧甚。

這里獲取狀態(tài)有兩種方式车荔,一個是在注入的組件的獲取方式,一個是在子組件獲取的方式戚扳。

因為在注入的組件似乎不能用 inject 來獲取忧便,所以只好直接返回 userInfo。于是就出現(xiàn)了兩種獲取狀態(tài)的方式帽借。

使用的時候不要弄混珠增。

如果可以保證在注入的組件里面不會用到狀態(tài)的話,可以把直接返回狀態(tài)的給去掉砍艾,這樣就不會混淆了蒂教。

使用 register 方式注入

引入js文件并不會自動注入,而是需要顯性使用 register 來注入脆荷。

這樣可以明確注入的組件凝垛,另外也可以避免每個組件都注入一個。

如果不使用 register 的話蜓谋,那么就是完全的本組件使用梦皮。

getUser

獲取狀態(tài)的時候,一個要注意使用 inject 桃焕,這樣獲取的才是共享的狀態(tài)届氢,否則就是本組件內(nèi)部的單獨(dú)的狀態(tài)了。

另外要加上 readonly覆旭,確保是只讀狀態(tài)。
當(dāng)然如果你就是喜歡直接改變狀態(tài)岖妄,那么也可以不加readonly型将。

setUser

這里有兩個注意點。
一個是要加到 inject 獲取出來的狀態(tài)上荐虐,否則就是只能改變本組件的狀態(tài)七兜,除非你在跟組件改狀態(tài)。

另一個就是應(yīng)為用的是 reactive福扬,所以不能直接賦值的方式來修改腕铸,但是一個一個屬性修改也太麻煩了,所以這里采用 Object.assign(_user, user) 的方式來修改屬性铛碑。

這是ES6提供的一種方法狠裹,用后面的對象的屬性,覆蓋前面的對象的屬性汽烦。

注意:這種方法有可能導(dǎo)致增加屬性涛菠。

使用 Symbol 避免重名

export const sysUserInfo = Symbol('userOnlineInfo')

一開始我沒把這個寫在 單獨(dú)的js文件里面,但是發(fā)現(xiàn)子組件里面讀取不出來狀態(tài),所以只好把 Symbol 放在單獨(dú)的js文件里面了俗冻。

一開始用他是想徹底堵住直接修改狀態(tài)的漏洞礁叔,但是發(fā)現(xiàn)好像還是不行。

所以現(xiàn)在就變成了避免重名迄薄、避免“魔術(shù)”的功能琅关。

似乎應(yīng)該用純大寫字母來命名,但是讥蔽,英語重來沒及格過涣易,看純大寫的實在頭疼。如果你們喜歡的話勤篮,你們可以用都毒。

反正組件里面也看不到。

根組件注入

import userState from './store-nf'
setup () {
    const { userInfo, register } = userState()
    // 在這個組件里面注入碰缔,子組件里面可以共享狀態(tài)
    register()
    
    setTimeout(() => {
      userInfo.userCode = '222222' // 只讀狀態(tài)账劲,不會修改,F(xiàn)12會給出警告金抡。
      console.log('userInfo--定時修改', userInfo)
    }, 500)
}

子組件調(diào)用

import userState from '../store-nf'
 setup () {
    const { userInfo, getUser } = userState()
    // 測試控件內(nèi)部修改
    const test = getUser()
    test.userNike = '4345555' // 只讀瀑焦,不讓改。
    // 使用指定的方法修改狀態(tài)
    setUser({ userCode: '22222' })
}

基本思路就是這樣梗肝。
現(xiàn)在這個樣子還是比較簡陋榛瓮,大概會有一些不足的地方。

模塊化

這樣使用本身就變成了一個個獨(dú)立的模塊巫击,或者是一個個獨(dú)立的管理類禀晓。

如果都是在根組件里面注入的話,那么就都是兄弟模塊坝锰,沒有上下級關(guān)系粹懒。

如果在不同的組件里面注入,那么依賴組件的層級關(guān)系來確定上下級的關(guān)系顷级。

這樣就避免的Vuex里面的模塊的命名空間的問題凫乖。

不過這樣也太分散了,是不是有點不便于統(tǒng)一管理呢弓颈?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末帽芽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子翔冀,更是在濱河造成了極大的恐慌导街,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纤子,死亡現(xiàn)場離奇詭異菊匿,居然都是意外死亡付呕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門跌捆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來徽职,“玉大人,你說我怎么就攤上這事佩厚∧范ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵抄瓦,是天一觀的道長潮瓶。 經(jīng)常有香客問我,道長钙姊,這世上最難降的妖魔是什么毯辅? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮煞额,結(jié)果婚禮上思恐,老公的妹妹穿的比我還像新娘。我一直安慰自己膊毁,他們只是感情好胀莹,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著婚温,像睡著了一般描焰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上栅螟,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天荆秦,我揣著相機(jī)與錄音,去河邊找鬼力图。 笑死萄凤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的搪哪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼坪圾,長吁一口氣:“原來是場噩夢啊……” “哼晓折!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兽泄,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤漓概,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后病梢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辱匿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年舔清,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吩蔑。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖填抬,靈堂內(nèi)的尸體忽然破棺而出烛芬,到底是詐尸還是另有隱情,我是刑警寧澤飒责,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布赘娄,位于F島的核電站,受9級特大地震影響宏蛉,放射性物質(zhì)發(fā)生泄漏遣臼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一拾并、第九天 我趴在偏房一處隱蔽的房頂上張望揍堰。 院中可真熱鬧,春花似錦辟灰、人聲如沸个榕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽西采。三九已至,卻和暖如春继控,著一層夾襖步出監(jiān)牢的瞬間械馆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工武通, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留霹崎,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓冶忱,卻偏偏與公主長得像尾菇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子囚枪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容