摘要:它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。狀態(tài)自管理應(yīng)用包含以下幾個(gè)部分,驅(qū)動(dòng)應(yīng)用的數(shù)據(jù)源,以聲明方式將映射到視圖,響應(yīng)在上的用戶輸入導(dǎo)致的狀態(tài)變化。
事情發(fā)生在上周(2019-06-06)團(tuán)隊(duì)技術(shù)分享的時(shí)候。
起因在于一個(gè)問題:vue 中多個(gè)組件如何使用同一個(gè)變量,我們叫這個(gè)變量為 baseConfig 吧。
說實(shí)話我沒想到那么多人不理解其中的知識(shí)。今天我整理一下發(fā)出來。
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。Vuex 可以幫助我們管理共享狀態(tài),并附帶了更多的概念和框架。這需要對(duì)短期和長(zhǎng)期效益進(jìn)行權(quán)衡。
狀態(tài)自管理應(yīng)用包含以下幾個(gè)部分:
state,驅(qū)動(dòng)應(yīng)用的數(shù)據(jù)源;
view,以聲明方式將 state 映射到視圖;
actions,響應(yīng)在 view 上的用戶輸入導(dǎo)致的狀態(tài)變化。
以下是一個(gè)表示“單向數(shù)據(jù)流”理念的簡(jiǎn)單示意:
Vuex 的應(yīng)用其實(shí)看完了上面的介紹,我們就明白,這是一個(gè)非常符合我們需求的工具。那么我們就來看看怎么去應(yīng)用。
mapState 輔助函數(shù) 當(dāng)一個(gè)組件需要獲取多個(gè)狀態(tài)時(shí)候,將這些狀態(tài)都聲明為計(jì)算屬性會(huì)有些重復(fù)和冗余。為了解決這個(gè)問題,我們可以使用 mapState 輔助函數(shù)幫助我們生成計(jì)算屬性。
從下面的例子可以看到,我們子組件中的值是通過計(jì)算屬性來從 store 中獲取的。這樣在通過 mutations 等方式改變之后,我們的值也會(huì)動(dòng)態(tài)更新。
當(dāng)然,你的頁面簡(jiǎn)單的時(shí)候,也不需要再去使用 Vuex,考慮一下后面的方案吧。
const store = new Vuex.Store({ state: { baseConfig: { server_name: "lilnong.top" } } }) // 創(chuàng)建一個(gè) User 組件 const Serv = { template: `方案二:父子組件傳參 父?jìng)鲄⒌姆绞?/b>{{ server_name }}`, computed: { server_name() { // this.$store return store.state.baseConfig.server_name } } } const app = new Vue({ el: "#app", store, // 這樣可以把 store 的實(shí)例注入所有的子組件 components: { Serv }, template: `` })
baseConfig 需要定義在最外面,然后給所有的子組件都傳遞進(jìn)去,當(dāng)有改變的時(shí)候,子組件也會(huì)跟著改變。
{ data: { baseConfig: { server_name: "lilnong.top" } } }子組件接受參數(shù)的方式
每個(gè)子組件都需要接收。
{ props:["server_name", "baseConfig"],//這種是無默認(rèn)值,無類型檢查的,正常使用不推薦這種寫法 }父子組件方案的優(yōu)缺點(diǎn)
所有的父組件都需要傳遞參數(shù),所有的子組件都要接收參數(shù)。
傳入的問題可以通過,傳入一個(gè)對(duì)象的所有參數(shù)來解決
方案二:路由組件傳參該方案也叫方案二,并不是我寫錯(cuò)了,是因?yàn)樗麄兊膱?chǎng)景是一樣。
在 Vue Router 的路由中,我們把組件配置在 routes 中,導(dǎo)致我們無法在模板之中傳遞參數(shù)。
這里我們需要使用他提供的 props 屬性來傳參,文檔地址。jsRun測(cè)試地址。lilnong.top測(cè)試地址
const Foo = { template: "foo" } const Bar = { template: "bar" } const routes = [ { path: "/foo", component: Foo }, { path: "/bar", component: Bar } ] const router = new VueRouter({ routes // (縮寫) 相當(dāng)于 routes: routes }) const app = new Vue({ router }).$mount("#app")
方案三:全局對(duì)象(store 模式)Hello App!
Go to Foo Go to Bar
簡(jiǎn)單狀態(tài)管理起步使用 --官方文檔
全局對(duì)象就是如下使用,定義一個(gè)全局對(duì)象,然后修改這個(gè)全局對(duì)象就好了
const sourceOfTruth = {} const vmA = new Vue({ data: sourceOfTruth }) const vmB = new Vue({ data: sourceOfTruth })store 模式
原理上來講,還是全局對(duì)象,但是通過簡(jiǎn)單的規(guī)定,來明確數(shù)據(jù)流向
var store = { debug: true, state: { message: "Hello!" }, setMessageAction (newValue) { if (this.debug) console.log("setMessageAction triggered with", newValue) this.state.message = newValue }, clearMessageAction () { if (this.debug) console.log("clearMessageAction triggered") this.state.message = "" } } var vmA = new Vue({ data: { privateState: {}, sharedState: store.state } }) var vmB = new Vue({ data: { privateState: {}, sharedState: store.state } })爭(zhēng)論核心:全局對(duì)象方案究竟行不行?原理?
好了,三種方案這里就已經(jīng)介紹完了。那開始看看我們的爭(zhēng)論:全局放個(gè)對(duì)象的方式不行(對(duì)方觀點(diǎn)),數(shù)據(jù)更新時(shí)組件不會(huì)自動(dòng)更新
先說原理,內(nèi)存地址vue 數(shù)據(jù)綁定的原理大家都懂吧?通過 defineProperty 來劫持,Dep 收集依賴等等。
對(duì)于對(duì)象類型的數(shù)據(jù),我們變量里面保存的其實(shí)是一個(gè)指向堆的地址,我們來看下面的這個(gè)例子。
var obj = {};//定義了一個(gè)對(duì)象,`obj` 存放的是一個(gè)地址 obj.a = 1;//通過 `obj` 的地址,找到對(duì)象,然后給對(duì)象里面放了 `a=1` ; var obj1 = obj;//把 `obj` 的地址,給 `obj1` 復(fù)制了一下 obj1.a = 2;//通過 `obj1` 的地址,找到對(duì)象,然后給對(duì)象里面放了 `a=2` ; //這個(gè)時(shí)候,對(duì)象里面存放的就是{a:2}//console.log(obj, obj1) //這里引出了另一個(gè)問題 深拷貝與淺拷貝
這里也就是我的核心原理。
定義一個(gè)對(duì)象(保存在 window 上)
通過對(duì)象變量保存的是地址的原理
我們?cè)谄渌M件都用 window 上的對(duì)象以此來達(dá)到目的。
再說場(chǎng)景,細(xì)化問題是不是看到上面的原理好簡(jiǎn)單?但是往往不是這么簡(jiǎn)單,下面咱們分析一下情況
window 上沒綁對(duì)象,而是其他類型這么辦?比如說 null 、 undefined
我也沒轍,大哥,看好上面的原理,主要原理就是地址引用。
對(duì)象覆蓋,就是如下的這個(gè)賦值場(chǎng)景。
其實(shí)我理解你是想給 obj 重新都賦值一下。
obj={}; obj2 = obj; obj.a = 1; obj2 = {a:2,b:3};//這里把 obj2 的地址換成了新的一個(gè)對(duì)象 //console.log(obj, obj2)
但是不能這樣寫,正確操作如下:
Object.assign(obj2, {a:2,b:3})
一個(gè)一個(gè)值的寫 obj2.a=2;obj2.b=3;
后添加的屬性,沒有計(jì)入 vue 的數(shù)據(jù)觀察隊(duì)列(新手經(jīng)常犯的錯(cuò)誤)
對(duì)象變更檢測(cè)注意事項(xiàng)
于 JavaScript 的限制,Vue 不能檢測(cè)對(duì)象屬性的添加或刪除:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 現(xiàn)在是響應(yīng)式的 vm.b = 2 // `vm.b` 不是響應(yīng)式的
對(duì)象解決方案 Vue.set(object, propertyName, value)
對(duì)象解決方案(實(shí)例內(nèi)) this.$set(object, propertyName, value)
數(shù)組更新檢測(cè)
將一些方法進(jìn)行了封裝 push()、pop()、shift()、unshift()、splice()、sort()、reverse()。
通過上面的方法來改變數(shù)組可以監(jiān)聽到改變。
由于 JavaScript 的限制,Vue 不能檢測(cè)以下數(shù)組的變動(dòng):
當(dāng)你利用索引直接設(shè)置一個(gè)數(shù)組項(xiàng)時(shí),例如:vm.items[indexOfItem] = newValue
當(dāng)你修改數(shù)組的長(zhǎng)度時(shí),例如:vm.items.length = newLength
總結(jié)共享數(shù)據(jù)三種方法
vuex
大而全,使用復(fù)雜
組件值傳遞
原生自帶,使用復(fù)雜,適合組件相關(guān)數(shù)據(jù)
store
簡(jiǎn)單,不適合復(fù)雜項(xiàng)目。工程的話,還是推薦 vuex
對(duì)象引用需要注意的地方
不能給變量二次賦值obj2={}
只有對(duì)象類型才是存地址, Array 與 Object。
String 與 Null等不包括在內(nèi)
增加數(shù)據(jù)要注意是否被觀察到
對(duì)象:注意 Vue.set
數(shù)組:使用規(guī)定方法
測(cè)試地址,采用 setTimeout 來模擬異步操作。當(dāng)時(shí)苦的一批,完了還沒保存。性感碼農(nóng),在線編程。
成功的說服了在場(chǎng)的兄弟們,然后周四就拖堂了。
VUEX 中文站
狀態(tài)管理 --vue官網(wǎng)
微信公眾號(hào):前端linong文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/104573.html
摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...
摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...
摘要:解決了組件之間同一狀態(tài)的共享問題。當(dāng)我們的應(yīng)用遇到多個(gè)組件之間的共享問題時(shí)會(huì)需要狀態(tài)管理核心狀態(tài)管理有個(gè)核心,分別是以及。當(dāng)錯(cuò)誤出現(xiàn)時(shí),我們現(xiàn)在也會(huì)有一個(gè)記錄之前發(fā)生了什么。此外,每個(gè)實(shí)例組件仍然可以擁有和管理自己的私有狀態(tài) 一,css部分 1,簡(jiǎn)單介紹下css權(quán)重優(yōu)先級(jí): 默認(rèn)樣式 .father{ width:300px; ...
閱讀 2432·2021-11-24 09:39
閱讀 3123·2021-10-15 09:39
閱讀 3180·2021-07-26 23:38
閱讀 2366·2019-08-30 11:14
閱讀 3468·2019-08-29 16:39
閱讀 1766·2019-08-29 15:23
閱讀 867·2019-08-29 13:01
閱讀 2731·2019-08-29 12:29