本篇文章主要介紹了詳解使用vuex進行選單管理,現在分享給大家,也給大家做個參考。
vuex 的優勢在複雜狀態管理中才能提現出來。
如果專案中有多級選單,且不同元件中散佈多個相同等級的選單,專案同一時刻各級選單有且僅有一個高亮,選單跳轉時除了路由改變,對應選單也要高亮(之前的恢復非高亮狀態),這便是個使用vuex 再好不過的場景。
使用DOM 操作進行簡單選單管理
使用DOM 進行選單管理,背後的想法是:在點擊選單的同時,將事件物件傳入事件處理程序,想讓目前高亮的menu 非高亮,再讓點擊的menu 高亮。
<p class="menu-url"> <span class="active userList" @click="menuClicked($event, 'userList')">注册</span> <span class="chargeList" @click="menuClicked($event, 'chargeList')">充值</span> <span class="buyList" @click="menuClicked($event, 'buyList')">购买</span> <span class="bangList" @click="menuClicked($event, 'bangList')">到期</span> <span class="withDrawList" @click="menuClicked($event, 'withDrawList')">提现</span> </p>
menuClicked (event, url) { // 当前高亮的 menu 非高亮 const currentActiveLink = this.querySelector('.active'); currentActiveLink.classList.remove('active'); // 当前点击的 menu 高亮 event.target.classList.add('active'); // 路由跳转 this.$router.push(`/panel/list/${url}`); },
這樣雖然實現了點擊切換時menu 高亮,但有一個bug:每次初始化都會使預設的menu 變成高亮,如果此時在非預設高亮的menu 中用戶手動刷新頁面,會導致menu 高亮錯誤(例如在buylist 頁面刷新頁面後,頁面內容依然停留在buylist,但高亮的菜單卻變成了userlist)。
如果要解決這個bug,就需要在本地儲存(刷新不改變儲存狀態) menu 狀態,本地儲存可以選擇不同的方案,在此不做討論,但可以肯定的是DOM 本地儲存控制menu 高亮的方案在專案逐漸變大以後會變得難以維護。
現在是 vuex 登場的時候了。
使用vuex 進行選單管理
使用vuex 進行選單管理需要在開發前就規劃好選單的層級
,以便在vuex 中分配state
和mutations
。
規劃層級
確定專案中哪些是一級選單,哪些是二級選單,以此類推… 這裡要注意的是,為簡化操作,同等級選單都以不同名稱命名,這樣在vuex 中就不需要專注在選單屬於那個頁面,只專注在狀態就好。選單層級通常如下:
|-root | | | |-first-menu1 | | |- second-menu1 | | |- second-menu2 | | |- second-menu3 | | | |-first-menu2 | |- second-menu3 | |- second-menu4 | |- second-menu5
在vuex 指派`state` 和`mutations`
不同層級的選單分別佔用一個`state`,至於`mutations`,本例不同`state` 分別對應寫了一個`mutations`,實際工作中為了更大成都減少程式碼復用,對於menu 的狀態管理可以只寫一個`mutations`,透過傳參判斷是更改哪個層級及對應的menu。
要注意的是 vuex 在頁面刷新後狀態會重新初始化,這顯然和管理選單所需功能不符(除了主動觸發,其他操作不能對選單產生影響)。可以透過vuex-persistedstate 改變vuex 預設生命週期,下面範例程式碼將vuex 狀態儲存在了cookie 中:
js
const store = new Vuex.Store({ state: { // 初始化 activeFirstMenu: 'firstMenu1', activeSecondMenu : 'secondMenu1', }, mutations: { // 更改一级菜单 changeFirstActiveMenu (state, menu) { state.activeFirstMenu = menu; }, // 更改二级二级菜单 changeSecondActiveMenu (state, menu) { state.activeSecondMenu = menu; } }, });
元件中渲染
在template 動態載入高亮class,透過vuex 中state 控制:
<p class="subMenu"> <span :class="{ activeSecondMenu: activeMenu.secondMenu1 }" @click="menuClicked('secondMenu1')">secondMenu1</span> </p> <p class="subMenu"> <span :class="{ activeSecondMenu: activeMenu.secondMenu2 }" @click="menuClicked('secondMenu2')">secondMenu2</span> </p> <p class="subMenu"> <span :class="{ activeSecondMenu: activeMenu.secondMenu3 }" @click="menuClicked('secondMenu3')">secondMenu3</span> </p>
寫js 時有個技巧:路由path 和對應高亮的menu 名稱最好相同,因為路由跳轉和高亮menu 直接相關,這樣可以減少一個參數:
data () { return { // 初始化 activeMenu: { // menu 名称相同,和对应路由的 path 相同 secondMenu1: '', secondMenu2: '', secondMenu3: '', }, }; }, computed: { activeMenuName () { // 检测 vuex 中 activeSecondMenu 的变化 return this.$store.state.activeSecondMenu; } }, methods: { menuClicked(path) { // 取消当前 tab 高亮 this.activeMenu[this.activeMenuName] = false; // 更新 vuex 状态及 menu 高亮 this.$store.commit("changeSecondActiveMenu", path); this.activeMenu[this.activeMenuName] = true; // 路由跳转 path 和对应 menu 名称相同 this.$router.push(`/somePath/${path}`); }, init () { // 刷新页面重置正确高亮菜单tab this.activeMenu[this.activeMenuName] = true; }, }, mounted: { this.init(); },
其他
#對於vuex 的最佳化
上文有談到,實際工作中為了更大程度實現程式碼重複使用,對於某個類別的狀態管理可以只寫一個mutations ,透過傳參(Payload )判斷更改內容。還是以menu 管理為例,可進行下面的最佳化:
vuex 最佳化後如下:
const store = new Vuex.Store({ // 其他代码略 mutations: { // 优化后代码,合并 changeFirstActiveMenu 和 changeSecondActiveMenu changeActiveMenu (state, menuInfo) { state[menuInfo.menuHierarchy] = menuInfo.name; } } });
元件js 部分最佳化後如下:
methods: { menuClicked(path) { // 其他代码略高亮 // 优化后代码:更改一级和二级菜单触发同个 mutation this.$store.commit("changeActiveMenu", { menuHierarchy: 'activeFirstMenu', name: path, }); this.$store.commit("changeActiveMenu", { menuHierarchy: 'activeSecondMenu', name: path, }); // 其他代码略 }, },
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
以上是如何使用vuex實現選單管理的詳細內容。更多資訊請關注PHP中文網其他相關文章!