使用 Vuex 管理應用狀態(tài)
1. 引入背景
像先前我們是有導航菜單欄收縮和展開功能的,但是因為組件封裝的原因,隱藏按鈕在頭部組件,而導航菜單在導航菜單組件,這樣就涉及到了組件收縮狀態(tài)的共享問題。收縮展開按鈕觸發(fā)收縮狀態(tài)的修改,導航菜單需要根據(jù)收縮狀態(tài)來設置導航欄的寬度。這樣就需要在收縮狀態(tài)變更時刷新導航菜單樣式。后續(xù)類似的組件狀態(tài)共享還會有許多。為了解決組件間狀態(tài)的共享,增加組件交互的易用性,我們引入 vuex 專門管理應用狀態(tài)。
2. 安裝依賴
執(zhí)行以下命令,安裝 vuex 依賴。
yarn add vuex
3. 添加配置
3.1 添加 Store
在 src 目錄下,新建一個 store 目錄,專門管理應用狀態(tài),在 index.js 中創(chuàng)建 store。
?
index.js
import Vue from 'vue' import vuex from 'vuex' Vue.use(vuex); const store = new vuex.Store({ state:{ collapse:false // 導航欄收縮狀態(tài) }, mutations:{ collapse(state){ // 改變收縮狀態(tài) state.collapse = !state.collapse; } } }) export default store
3.2 引入 Store
?在 main.js 引入 store
4. 使用 Store
4.1 修改狀態(tài)
在原先響應折疊導航欄的函數(shù)內(nèi)替換原有邏輯,改為發(fā)送提交請求來改變收縮狀態(tài)。
4.2 獲取狀態(tài)
在原先引用 collapse 的地方改為引用 $store.state.collapse 。
根據(jù)收縮狀態(tài)綁定不同樣式,就可以實現(xiàn)導航菜單欄根據(jù)收縮狀態(tài)更新頁面效果了。
MenuBar.vue
HeadBar.vue
?Main.vue
5. 測試效果
進入主頁,點擊收縮按鈕,效果如下圖。
Store 模塊化
現(xiàn)在我們的狀態(tài)都維護在index.js,狀態(tài)一多就會出現(xiàn)臃腫,這里可以根據(jù)需求進行模塊化。
1. 文件結構
模塊化后的文件結構
2. Store 封裝
改寫index.js,引入模塊化,這里把之前的狀態(tài)抽取到AppStore,后續(xù)可能還會有UserStore、MenuStore之類的。
import Vue from 'vue' import vuex from 'vuex' Vue.use(vuex); import AppStore from './modules/AppStore.js'; const store = new vuex.Store({ modules: { app: AppStore // 其他 } }) export default store
AppStore.js
export default { state: { appName: "I like Kitty", // 應用名稱 collapse:false // 導航欄收縮狀態(tài) }, getters: { collapse(state){// 對應著上面state return collapse; } }, mutations: { collapse(state){ // 改變收縮狀態(tài) state.collapse = !state.collapse; } }, actions: { } }
?3. 狀態(tài)引用
在引用 store 狀態(tài)的地方加上模塊名稱
如果一個文件內(nèi)引用過多,嫌引用路勁又長又臭,可以使用 mapState、mapGetter、mapActions 工具進行簡化。
如 MenuBar.vue 中引用較多,我們用 mapState 簡化對屬性的引用。如下圖,給狀態(tài)賦予別名。
?引用狀態(tài)的地方就可以直接用上面定義的別名進行訪問了。
?
mapState、mapGetter、mapActions 工具對于文件內(nèi)大量又長又臭的狀態(tài)引用時非常有用,可以適當?shù)倪\用。
封裝收縮組件
1. 組件封裝
?如下圖,新建目錄和文件,封裝收縮組件展開導航欄組件。
Hamburger/index.vue
<template> <svg t="1492500959545" @click="toggleClick" class="hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"> <path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z" p-id="1692"></path> <path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z" p-id="1693"></path> <path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z" p-id="1694"></path> </svg> </template> <script> export default { name: 'hamburger', props: { isActive: { type: Boolean, default: false }, toggleClick: { type: Function, default: null } } } </script> <style scoped> .hamburger { display: inline-block; cursor: pointer; width: 20px; height: 20px; transform: rotate(90deg); transition: .38s; transform-origin: 50% 50%; } .hamburger.is-active { transform: rotate(0deg); } </style>
2. 引入組件
HeadBar.vue 中引入組件
響應函數(shù),通過 store 修改收縮狀態(tài)
3. 測試效果
進入主頁,效果如下圖。
封裝面包屑組件
將面包屑從主內(nèi)容中抽取出來,封裝成 BreadCrumb。
BreadCrumb/index.vue
<template> <el-breadcrumb separator="/" class="breadcrumb"> <el-breadcrumb-item v-for="item in $route.matched" :key="item.path"> <a href="www.baidu.com">{{ item.name }}</a> </el-breadcrumb-item> </el-breadcrumb> </template> <script> export default { data() { return { }; }, methods: { }, mounted() { } }; </script> <style scoped lang="scss"> .breadcrumb { padding: 10px; border-color: rgba(38, 86, 114, 0.2); border-bottom-width: 1px; border-bottom-style: solid; // background: rgba(180, 189, 196, 0.1); } </style>
main.js 中 引入
動態(tài)換膚
1. 功能背景
之前的動態(tài)換膚,只能刷新 Element 相關組件的顏色,而如果我們希望在換膚的時候我們的頭部區(qū)域也同步改變就需要做進一步的修改了。接下來,我們就實現(xiàn)這個功能,賦予換膚組件在更新 Element 組件顏色的時候,可以定制插入一些自定義的操作。
2. 改進ThemePicker?
修改 ThemePicker 插件, 綁定導出函數(shù)和主題色參數(shù)。
3. 父組件函數(shù)綁定
在父組件綁定處理函數(shù),增加自定義同步更新邏輯。
這里是切換主題顏色的時候,設置 store 狀態(tài),保存共享主題色,這樣其他綁定主題色的組件都可以自動更新了。
4. 添加共享狀態(tài)
在 store 中定義主題色相關的狀態(tài)。
5. 共享狀態(tài)引入
在要使用的組件處引入主題色狀態(tài)。
組件樣式綁定主題色狀態(tài),主題色并更時,更新組件背景色樣式。
6. 測試效果
進入主頁,點擊動態(tài)換膚取色器,換膚效果如下。文章來源:http://www.zghlxwxcb.cn/news/detail-701243.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-701243.html
到了這里,關于Vue + Element UI 前端篇(八):管理應用狀態(tài)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!