VBox持续进行中,哀家苦啊,有没有谁给个star。
vuex是vue用于数据存储的,和redux充当同样的角色。
最近在VBox开发的时候遇到的问题,页面刷新或者关闭浏览器再次打开的时候数据归零。这是头疼的问题。
网上搜,大家的方案都是把数据转移到 localStorage或者其他持久化存储(例如indexDB)。
这倒是可以,我在设计之初因为匆忙,没有考虑周全,这下好,然不成每个 mutation都去存一下。
这个弄的我很不开心,周六在公司,本来就困的要死,又想不到合理的解决方案,昏昏沉沉睡着了。
醒了后,最初想采用 柯里化和高阶函数来解决这个问题,很可惜,没有正解。
最小化修改,又不想动现有代码,代理二字最为不过。记得上次我写IBook之初,也用Proxy来拦截修改,同时存数据到磁盘文件。
没错方案就是 ES6的Proxy,尝试之后,确实是可以的。
源码地址:https://github.com/xiangwenhu/vbox/tree/master/src/utils
这里有两个问题
1. 初始值的问题。
2. 我要可以配置哪些字段需要持久化,store里面的数据,不代表我都需要持久化。
首先解决是 localStorage存储的问题,因为需要转换字符串,简单封装一个 LStorage.js,当然你也可以用 https://github.com/tsironis/lockr , https://github.com/nbubna/store 或者你喜欢的,小轮子我就自己写了。
const ls = window.localStorage
// https://github.com/tsironis/lockr
export default {
getItem(key) {
try {
return JSON.parse(ls.getItem(key))
} catch (err) {
return null
}
},
setItem(key, val) {
ls.setItem(key, JSON.stringify(val))
},
clear() {
ls.clear()
},
keys() {
return ls.keys()
},
removeItem(key) {
ls.removeItem(key)
}
}
其次就是代理的简单封装,LSproxy.js
这个版本还是有问题的,现在只能代理二级属性,对现在的我而言已经是够用了的。
createHanlder 创建二级属性的代理
copy 复制对象,当然你可以写更加兼容优雅的方法
proxy 创建state的代理
import LStorage from './LStorage'
/**
* 代理二级属性
* @param {*} lsKey 存在localStorage的key
* @param {*} pk 一级属性的key
*/
function createHanlder(lsKey, pk) {
return {
set: function (target, key, value, receiver) {
let item = LStorage.getItem(lsKey)
if (item && item[pk]) {
item[pk][key] = value
LStorage.setItem(lsKey, item)
}
return Reflect.set(target, key, value, receiver)
}
}
}
/**
* 仅仅存需要存放的数据
* @param {*} source
* @param {*} keys
*/
function copy(source, keys = []) {
if (!source) {
return source
}
let d = Object.create(null)
keys.forEach(k => { d[k] = source[k] })
return d
}
/**
* 代理state
* @param {*} initState 初始化的值
* @param {*} lsKey localStorage的key
* @param {*} keys 需要存储的键
*/
const proxy = function (initState, lsKey, keys = []) {
let ks = keys, obj = Object.assign({}, initState, LStorage.getItem(lsKey))
// 代理二级属性
keys.forEach(k => {
obj[k] = new Proxy(obj[k], createHanlder(lsKey, k))
})
// 存入合并的值
LStorage.setItem(lsKey, copy(obj, keys))
return new Proxy(obj, {
set: function (target, key, value, receiver) {
ks.indexOf(key) >= 0 && LStorage.setItem(lsKey, copy(target, keys))
return Reflect.set(target, key, value, receiver)
}
})
}
export { proxy }
调用这边,基本就没有什么变化, 就多了一句 state = proxy(state, 'playing', ['list'])
import { proxy } from '../utils/LSProxy'
let state = {
list: [],
current: null
}
state = proxy(state, 'playing', ['list'])
const mutations = {
/**
* 添加歌曲
* @param {*} state
* @param {*} song 歌曲信息
*/
addSong(state, song) {
let index = state.list.findIndex(s => s.songmid === song.songmid)
if (index < 0) {
state.list.push(song)
}
},
/**
* 添加歌曲
* @param {*} state 内置
* @param {*} songs 歌曲列表
*/
addSongs(state, songs) {
let index = -1
songs.forEach(song => {
index = state.list.findIndex(s => s.songmid === song.songmid)
if (index < 0) {
state.list.push(song)
}
})
},
/**
* 删除歌曲
* @param {*} state
* @param {*} songmid 歌曲媒体id
*/
removeSong(state, songmid) {
let index = state.list.findIndex(s => s.songmid === songmid)
index >= 0 && state.list.splice(index, 1)
},
/**
* 批量删除歌曲
* @param {*} state
* @param {*} songmids 歌曲媒体列表
*/
removeSongs(state, songmids = []) {
let index = -1
songmids.forEach(songmid => {
index = state.list.findIndex(s => s.songmid === songmid)
index >= 0 && state.list.splice(index, 1)
})
},
/**
* 播放下一首,
* @param {*} state
* @param {*} song 为空
*/
next(state, song) {
// 如果song不为空,表示是插放,(前提是已经添加到playing)
if (song) {
let index = state.list.findIndex(s => s.songmid === song.songmid)
if (index >= 0) {
state.current = state.list[index]
return
}
return
}
// 如果current为空,表示没有播放的歌曲
if (!state.current && state.list && state.list.length > 0) {
state.current = state.list[0]
return
}
// 如果不是插放,并且current不为空
if (!song && state.current) {
// 播放的歌曲是不是在当前的列表
let index = state.list.findIndex(s => s.songmid === state.current.songmid)
// 如果在歌曲列表里面,接着播放下首
if (index >= 0) {
state.current = (index === state.list.length - 1 "_blank" href="https://www.jb51.net/article/117701.htm">解决VUEX刷新的时候出现数据消失
《魔兽世界》大逃杀!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]