在vue的项目里面,组件之间相互通信的方式有很多,比如props/$emit、$on/$emit、vuex以及利用ref通信等方式。跨组件有这么多的通信方式可以选择,但是当需求要求我们跨页面通信怎么办呢?
由于每个页面都是一个独立的vue实例,页面与页面之间不存在数据上的沟通,所以,从vue框架上暂时行不通了。然后想到可以利用页面缓存的方式来进行通信。
在Web Storage中有两种储存数据的方式,分别是sessionStorage和localStorage,他们之间的区别在于生命周期的不同以及作用域(同源条件下)的不同。sessionStorage仅在当前会话中有效,关闭页面或者浏览器后数据会被自动清除,其作用域仅限于当前页面,不能跨tab页面访问。localStorage的生命周期是永久有效,只要是不主动删除,数据会一直被存储下来,其作用域也可以跨同源的页面访问。
有了localStorage跨页面的作用域,就可以做到页面之间的通信了,这下只要能解决如何监听其存储数据的变化就能实现了。于是想到了一个比较粗暴的方式——利用定时器:在一定间隔时间内获取localStorage中的数据并更新到获取数据的页面中去,这样便实现了数据的监听。但这样未免也太耗费性能了,为了少耗费性能而拉长时间间隔,但数据又总是更新不及时。这样这个方式就被待定了。
这时了解到有一个专门用来监听本地存储的数据变化的事件为Storage事件:Web Storage API内建了一套事件通知机制,当存储区域的内容发生改变(包括增加、修改、删除数据)时,就会自动触发 storage 事件,并把它发送给所有感兴趣的监听者。所有支持 localStorage 的浏览器都支持 storage 事件,包括 IE8。但IE 8不支持 W3C 标准的 addEventListener。因此,为了监听 storage 事件,还需要检测浏览器支持哪种事件机制:
if (window.addEventListener) {
window.addEventListener("storage", handleStorage, false);
} else {
window.attachEvent("onstorage", handleStorage);
}
有了这个storage事件,跨页面通信就变得很容易了:
<!--发送数据页面-->
<template>
<div class="home">
<h1>发送数据页面</h1>
<input type="text" @input="input" v-model="value"/>
</div>
</template>
<script>
export default {
name: 'Home',
data () {
return {
value: 'test'
}
},
methods: {
input () {
localStorage.setItem("test", this.value)
}
},
created () {
localStorage.setItem("test", this.value)
}
}
</script>
<!--接收数据页面-->
<template>
<div class="about">
<h1>接收数据页面</h1>
获取到的值:{{value}}
</div>
</template>
<script>
export default {
name: 'about',
data () {
return {
value: ''
}
},
created () {
window.addEventListener("storage", e => {
if (e.key === "test") {
this.value = e.newValue
}
})
}
}
</script>
网友评论