项目中,用vuex管理状态,遇到一个需求:点击查看,打开一个新窗口,在这个新窗孔中展示内容,
原本的想法是:在点击之后,触发click事件,在这个事件中,用dispatch提交突变,从而从新闻数组中找出所需的新闻展示,代码如下所示:
组件里的toDetail方法
methods: {
toDetail: function () {
const {href} = this.$router.resolve({path: 'news/detail'})
this.$store.dispatch('selectNews', {
id: this.newsItem.id,
kind: this.newsItem.channelName
})
window.open(href, '_blank')
}
}
模块里的mutation,用action调用(没给出)
在这个SELECT_NEWS中我会根据传过来的新闻id和种类找到唯一对应的那则新闻,然后记录在states中
SELECT_NEWS: (states, news) => {
let index, newsIndex
index = states.allNews.findIndex((item) => item.kind === 'recommend')
if (index === -1) return
if ((newsIndex = states.allNews[index].news.findIndex((item) => item.id === news.id)) !== -1) {
states.newsDetail = states.allNews[index].news[newsIndex] // 选出所需的新闻
}
}
可是问题出现了,在我打开的新窗口中,就是显示不了数据,当我打印出this.$store.getter.newsDetail发现它是空对象,但如果
我没有开打一个新窗口this.$store.getter.newsDetail里却包含了所需的数据,
mounted: function () {
this.news = this.$store.getters.newsDetail
console.log(this.$store.getters.newsDetail) // => {}
}
这让我很不解,查了资料,发现这可能和vuex只要一刷新数据会丢失有关,最后我改用了lessionStorage代码如下所示
lessionStorage用键值对的方式存储,很方便
在传对象的时候,可以先用JSON.stringify把对象变为字符串,在接受的时候用JSON.parse解析为对象就行了
toDetail: function () {
const {href} = this.$router.resolve({path: 'news/detail'})
this.$store.dispatch('selectNews', {
id: this.newsItem.id,
kind: this.newsItem.channelName
})
window.open(href, '_blank')
}
SELECT_NEWS: (states, news) => {
let index, newsIndex
index = states.allNews.findIndex((item) => item.kind === 'recommend') // index记录这则新闻所在的大类的在数组里的位置
if (index === -1) return
if ((newsIndex = states.allNews[index].news.findIndex((item) => item.id === news.id)) !== -1) {
states.newsDetail = states.allNews[index].news[newsIndex] // 选出所需的新闻
console.log(states.newsDetail)
sessionStorage.setItem('news', JSON.stringify(states.newsDetail))
}
}
mounted: function () {
this.news = JSON.parse(sessionStorage.getItem('news'))
}