M站的开发还剩下最后2天,基本只剩下优化工作,但是今天在优化点赞功能的时候出现了个小问题:
路由:http://mob.gulugulu.cn/forum/:forumId
在项目的store中,有一处列表页的缓存,是根据:forumId
为key值,存储的数据。大致结构如下:
forumsDetailList: {
// eg:单个G圈列表的详情
// 11234123131414:{
// sticky:{ //置顶帖
// items:[]
// },
// topics:{ //标准帖
// items:[],
// step:10,
// score:0,
// status:true,
// },
// essence:{ //精华帖
// items:[],
// step:10,
// sinceId:0,
// status:true, //此类型是否还有更多数据
// },
// score:0,
// scrollTop : ''
// }
},
这种结构在store初始化的时候并未显式声明出所有key值,所有的key值都是后期通过用户操作后动态插入的,于是就有一个问题,vue在提倡显式声明对象,然后将对象转变为observer对象,动态插值会导致无法将新插入的属性转变为observer对象,于是后期操作此类数据时会导致无法刷新视图。解决思路:将新加入的属性,通过Obeject.assign()
方法合并到已被Vue监视的属性节点上,即可将新属性转变为observer对象
//最初的动态插值方式(无法被监视):
state.forumsDetailList[key] = {}
//后改为(新加入的值可被监视):
state.forumsDetailList[key] = {}
state.forumsDetailList = Object.assign({}, state.forumsDetailList)
//拓展更复杂的数据结构
if(sticky){
state.forumsDetailList[key]['sticky'] = sticky
state.forumsDetailList[key] = Object.assign({}, state.forumsDetailList[key])
}
if(topics){
state.forumsDetailList[key]['topics'] = topics
state.forumsDetailList[key] = Object.assign({}, state.forumsDetailList[key])
}
if(essence){
state.forumsDetailList[key]['essence'] = essence
state.forumsDetailList[key] = Object.assign({}, state.forumsDetailList[key])
}
关于Object.assign()
方法,请访问:
MDN Doc
vue 文档-深入响应式原理