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