關于vuex更新視圖引發(fā)的一些思考詳析
vuex可以集中式存儲管理應用的所有組件的狀態(tài),當 Vue 組件從 store 中讀取狀態(tài)的時候,若 store 中的狀態(tài)發(fā)生變化,那么相應的組件也會相應地得到高效更新
但是,最近踩了vuex的坑:
場景
- 第一次進入頁面加載數(shù)據(jù),數(shù)據(jù)不顯示,點擊某個按鈕或者切換頁面后,數(shù)據(jù)會展示出來
- 通過分析發(fā)現(xiàn),當?shù)谝淮渭虞d頁面的時候,獲取數(shù)據(jù)的數(shù)據(jù)為{} (空對象),當數(shù)據(jù)獲取完畢,執(zhí)行commit()
- 而此時通過commit()已經(jīng)改變了state中的數(shù)據(jù),在頁面中通過computed也可以獲取更新后的數(shù)據(jù)。但是視圖沒有更新,獲取的數(shù)據(jù)沒有展示出來
解決
嘗試在頁面中發(fā)送commit()來再次更新視圖,無效
將Vue.set(state, 'myData', data),無效
......
最終方案:
代碼中所聲明的對象里面的key是動態(tài)的,所以初始只聲明了{ }。
原來,數(shù)據(jù)是數(shù)組的時候,不能通過索引直接進行賦值,也不能修改數(shù)組的長度。 而Vuex只會跟蹤在對象創(chuàng)建時就存在的屬性,新添加到對象上的新屬性不會觸發(fā)更新。
并且循環(huán)嵌套層級太深,視圖也可能不更新
最終,給數(shù)組對象賦值,這里轉化了一下寫法,生效。具體如下:
const store = new Vuex.Store({ state: { myData: [] }, mutations: { setData(state, data) { // state.myData = data 不更新視圖 Vue.set(state, 'myData', JSON.parse(JSON.stringify(data))) } }, actions: { myFn () { store.commit('setData') } } }) export default store
如果添加了新的對象屬性,也可以使用Object.assign(),但必須深拷貝(否則加到對象上的新屬性不會觸發(fā)更新)
let someObject = Object.assign({}, someObject, {newField: value}) // 深拷貝 // Object.assign(this.someObject, { key: 1 }) // 淺拷貝
總結
- 不能直接去改變 store 中的狀態(tài)。改變 store 中的狀態(tài)的需要提交 (commit) mutation
- 在組件中調(diào)用 store 中的狀態(tài)在計算屬性中返回即可獲取,也可以直接$store.state來獲取
computed: { myData () { return store.state.myData } }, mounted() { console.log(this.store.state.myData) }
為數(shù)組添加新屬性并不會觸發(fā)視圖更新,因為vue沒有給新屬性增加get和set監(jiān)聽
賦值的數(shù)據(jù),如果循環(huán)嵌套層級太深,可能會導致視圖不更新
擴展
這些方法操作數(shù)組,vue可以檢測到數(shù)據(jù)變化:
push() pop() shift() unshift() splice() sort() reverse()
而下面這些不會改變原數(shù)組(返回了新數(shù)組),vue檢測不到:
filter() concat() slice()
到此這篇關于vuex更新視圖引發(fā)的一些思考的文章就介紹到這了,更多相關vuex更新視圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue源碼解析之Template轉化為AST的實現(xiàn)方法
這篇文章主要介紹了Vue源碼解析之Template轉化為AST的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12