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,
});
// 其他代码略
},
},
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]