国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解使用vuex進行菜單管理

2019-11-19 14:40:35
字體:
來源:轉載
供稿:網友

vuex 的優勢在復雜狀態管理中才能提現出來。

如果項目中有多級菜單,且不同組件中散布多個相同級別的菜單,項目同一時刻各級菜單有且僅有一個高亮,菜單跳轉時除了路由改變,相應菜單也要高亮(之前的恢復非高亮狀態),這便是個使用 vuex 再好不過的場景。

使用 DOM 操作進行簡單菜單管理

使用 DOM 進行菜單管理,背后的思想是:在點擊菜單的同時,將事件對象傳入事件處理程序,想讓當前高亮的 menu 非高亮,再讓點擊的 menu 高亮。

<div 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></div>
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 控制:

<div class="subMenu"> <span :class="{ activeSecondMenu: activeMenu.secondMenu1 }" @click="menuClicked('secondMenu1')">secondMenu1</span></div><div class="subMenu"> <span :class="{ activeSecondMenu: activeMenu.secondMenu2 }" @click="menuClicked('secondMenu2')">secondMenu2</span></div><div class="subMenu"> <span :class="{ activeSecondMenu: activeMenu.secondMenu3 }" @click="menuClicked('secondMenu3')">secondMenu3</span></div>

寫 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,  });  // 其他代碼略 },},

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 南溪县| 保靖县| 蒙阴县| 皋兰县| 读书| 济南市| 永安市| 凤翔县| 临夏市| 洞口县| 白玉县| 玛多县| 天镇县| 温州市| 土默特右旗| 禄丰县| 北海市| 马关县| 佳木斯市| 社旗县| 交城县| 永兴县| 宝兴县| 榆林市| 四子王旗| 平南县| 湖南省| 米易县| 贡山| 海城市| 碌曲县| 永靖县| 灵川县| 曲沃县| 汪清县| 两当县| 凤翔县| 类乌齐县| 七台河市| 灯塔市| 台湾省|