做網(wǎng)站建站點(diǎn)搜索引擎營銷的簡稱是
Vuex是什么
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。
簡而言之就是用來存數(shù)據(jù),可以有效減少使用組件傳參出現(xiàn)的問題。
基本元素:store(里面存數(shù)據(jù)),mutation(里面修改數(shù)據(jù)),action(里面異步調(diào)用mutation來修改數(shù)據(jù)),getter(獲取數(shù)據(jù))
以下是一個(gè)表示“單向數(shù)據(jù)流”理念的簡單示意:
但是,當(dāng)我們的應(yīng)用遇到多個(gè)組件共享狀態(tài)時(shí),單向數(shù)據(jù)流的簡潔性很容易被破壞:
- 多個(gè)視圖依賴于同一狀態(tài)。
- 來自不同視圖的行為需要變更同一狀態(tài)。
因此,我們把組件的共享狀態(tài)抽取出來,以一個(gè)全局單例模式管理。在這種模式下,我們的組件樹構(gòu)成了一個(gè)巨大的“視圖”,不管在樹的哪個(gè)位置,任何組件都能獲取狀態(tài)或者觸發(fā)行為!這就是vuex的產(chǎn)生。
通過定義和隔離狀態(tài)管理中的各種概念并通過強(qiáng)制規(guī)則維持視圖和狀態(tài)間的獨(dú)立性,我們的代碼將會(huì)變得更結(jié)構(gòu)化且易維護(hù)。這就是 Vuex 背后的基本思想。
Vuex 是專門為 Vue.js 設(shè)計(jì)的狀態(tài)管理庫,以利用 Vue.js 的細(xì)粒度數(shù)據(jù)響應(yīng)機(jī)制來進(jìn)行高效的狀態(tài)更新。
如果你想交互式地學(xué)習(xí) Vuex,可以看這個(gè) Scrimba 上的 Vuex 課程,它將錄屏和代碼試驗(yàn)場混合在了一起,你可以隨時(shí)暫停并嘗試。
優(yōu)勢與使用場景
- Vuex的狀態(tài)存儲(chǔ)是響應(yīng)式的,可跟蹤每一個(gè)狀態(tài)變化,一旦它改變,所有關(guān)聯(lián)組件都會(huì)自動(dòng)更新相對(duì)應(yīng)的數(shù)據(jù)。
- 共享數(shù)據(jù),解決了非父子組件的消息傳遞(將數(shù)據(jù)存放在state中)。
- 統(tǒng)一狀態(tài)管理,減少了請(qǐng)求次數(shù),有些情景可以直接從內(nèi)存中的state獲取數(shù)據(jù)。
Vuex與全局變量區(qū)別
vuex | 全局變量 |
---|---|
不能直接改變store里面的變量,由統(tǒng)一的方法修改數(shù)據(jù) | 可以任意修改 |
每個(gè)組件可以根據(jù)自己vuex的變量名引用不受影響 | 全局變量可能操作命名污染 |
解決了多組件之間通信的問題 | 跨頁面數(shù)據(jù)共享 |
適用于多模塊、業(yè)務(wù)關(guān)系復(fù)雜的中大型項(xiàng)目 | 適用于demo或者小型項(xiàng)目 |
什么時(shí)候需要用vuex?
- 當(dāng)一個(gè)組件需要多次派發(fā)事件時(shí)。例如購物車數(shù)量加減。
- 跨組件共享數(shù)據(jù)、跨頁面共享數(shù)據(jù)。例如訂單狀態(tài)更新。
- 需要持久化的數(shù)據(jù)。例如登錄后用戶的信息。
- 當(dāng)您需要開發(fā)中大型應(yīng)用,適合復(fù)雜的多模塊多頁面的數(shù)據(jù)交互,考慮如何更好地在組件外部管理狀態(tài)時(shí)。
核心概念
每一個(gè) Vuex 應(yīng)用的核心就是 store
(倉庫),它包含著你的應(yīng)用中大部分的狀態(tài) state
。
狀態(tài)管理有5個(gè)核心:state(存數(shù)據(jù))
、getter(獲取數(shù)據(jù))
、mutation(修改數(shù)據(jù))
、action(異步調(diào)用mutation來修改數(shù)據(jù))
、module(模塊)
Vuex 在vue3版本中的使用
uniapp已經(jīng)集成了vuex,所以我們只需要直接引用即可。
1. 引用
在main.js
文件中添加如下配置:
import store from '@/store';// vuex vue3 寫法
// #ifdef VUE3
import {createSSRApp
} from 'vue'
export function createApp() {const app = createSSRApp(App)// 引入Vuexapp.use(store)return {app,// Vuex // 如果 nvue 使用 vuex 的各種map工具方法時(shí),必須 return Vuex}
}
// #endif
2. 初始化
在項(xiàng)目根目錄創(chuàng)建store
文件夾,里面創(chuàng)建index.js
,內(nèi)容如下:
import {createStore
} from "vuex";export default createStore({state: {isDev: true, // 開發(fā)環(huán)境true,上線需要改成falsetoken: "", //Authorizationuid:'527',},mutations: {// 定義mutations,用于修改狀態(tài)(同步)updateUid(state, payload) {state.uid = payload},updateToken(state, payload) {state.token = payload},},actions: {// 定義actions,用于修改狀態(tài)(異步)// 2秒后更新狀態(tài)updateUid(context, payload) {setTimeout(() => {context.commit('updateUid', payload)}, 2000)}// updateUid(context, payload) {// context.commit('updateUid', payload)// }},getters: {// 定義一個(gè)gettersformatUid(state) {return state.uid + ' Tom'}},modules: {}
});
3. 頁面中使用
<script>import store from '@/store/index.js'; //需要引入storeexport default {data() {return {}},methods: {useStore() {console.log('updateUid1111', store.state.uid);// 異步修改store.dispatch('updateUid', 123456)// 同步修改store.commit('updateUid', 654321)console.log('updateUid1222', store.state.uid);}}}
</script>
注意:上述token
重新打開應(yīng)用時(shí),會(huì)調(diào)用默認(rèn)值,需要做持久化處理
Vuex的優(yōu)化
1. 拓展提升(動(dòng)態(tài)存值,持久化處理
)
通過上述的index.js
文件我們可以看到針對(duì)不同的狀態(tài),需要寫對(duì)應(yīng)的mutations
,比較繁瑣??梢钥紤]通過以下代碼進(jìn)行優(yōu)化:
import {createStore
} from "vuex";let lifeData = {}
try {lifeData = uni.getStorageSync('lifeData')
} catch (e) {
}// 需要永久存儲(chǔ),且下次APP啟動(dòng)需要取出的,在state中的變量名
let saveStateKeys = ['vuex_user', 'vuex_token',...]// 保存變量到本地存儲(chǔ)中
const saveLifeData = function(key, value) {// 判斷變量名是否在需要存儲(chǔ)的數(shù)組中if (saveStateKeys.indexOf(key) != -1) {// 獲取本地存儲(chǔ)的lifeData對(duì)象,將變量添加到對(duì)象中let tmp = uni.getStorageSync('lifeData');// 第一次打開APP,不存在lifeData變量,故放一個(gè){}空對(duì)象tmp = tmp ? tmp : {};tmp[key] = value;// 執(zhí)行這一步后,所有需要存儲(chǔ)的變量,都掛載在本地的lifeData對(duì)象中uni.setStorageSync('lifeData', tmp);}
}export default createStore({state: {isDev: true, // 開發(fā)環(huán)境true,上線需要改成falsetoken: "", //Authorizationvuex_token: lifeData.vuex_token ? lifeData.vuex_token : '',},mutations: {// 定義mutations,用于修改狀態(tài)(同步)updateUid(state, payload) {state.uid = payload},updateToken(state, payload) {state.token = payload},$uStore(state, payload) {let nameArr = payload.name.split('.');let saveKey = '';let len = nameArr.length;if (nameArr.length >= 2) {let obj = state[nameArr[0]];for (let i = 1; i < len - 1; i++) {obj = obj[nameArr[i]];}obj[nameArr[len - 1]] = payload.value;saveKey = nameArr[0];} else {state[payload.name] = payload.value;saveKey = payload.name;}saveLifeData(saveKey, state[saveKey])}},actions: {// 定義actions,用于修改狀態(tài)(異步)// 2秒后更新狀態(tài)updateUid(context, payload) {setTimeout(() => {context.commit('updateUid', payload)}, 2000)}// updateUid(context, payload) {// context.commit('updateUid', payload)// }},getters: {// 定義一個(gè)gettersformatUid(state) {return state.uid + ' Tom'}},modules: {}
});
2. 頁面中使用
<script>import store from '@/store/index.js'; //需要引入storeexport default {data() {return {}},methods: {useStore() {console.log('updateUid1111', store.state.uid);// 異步修改store.dispatch('updateUid', 123456)// 同步修改store.commit('updateUid', 654321)// 動(dòng)態(tài)存儲(chǔ)store.commit('$uStore', {name: 'vuex_token',// vuex_token 可以為任何你需要存儲(chǔ)的狀態(tài)value: res.token})console.log('updateUid1222', store.state.uid);console.log('vuex_token1222', store.state.vuex_token);}}}
</script>
參考資料
狀態(tài)管理Vuex
Uniapp在vue3下使用vuex
uniapp vue3中vuex的使用