目标: 使用Vue内置标签keep-alive实现对首页和城市选择页的性能优化
- 在浏览器中Network下的XHR可以发现,在每一次发生页面切换的时候都会有一次ajax请求,原因是:比如在Home.vue中,每一次页面更新的时候页面都会被重新渲染,所以它的mounted生命周期钩子就会就会重新执行,ajax数据就会被重新获取。每一次都要发出ajax请求,性能是很低的,能不能在请求一次后将内容存储起来?
找到程序的入口组件App.vue,<router-view>
显示的是路由所对应的内容,可以在<router-view>
外部包裹一个<keep-alive></keep-alive>
标签,这个标签是vue自带的一个标签。这个标签的意思是:路由的内容被加载过一次之后就把路由中的内容放到内存之中,下次再进这个路由的时候就不需要重新渲染这个组件,只需要从以前的内存中将数据拿出来显示在页面上就可以了。
- 一个逻辑问题:首页是上海的时候显示上海的内容,当在城市选择页选择北京的时候,首页应该显示的是北京的内容,所以,在城市改变的时候,首页还是需要再重新加载一次ajax请求的。
代码调整:
在Home.vue组件中,发送ajax请求的时候应该是:
getHomeInfo () {
axios.get('/api/index.json?city=' + this.city)
.then(this.getHomeInfoSucc)
}
其中的this.city是引入vuex后使用计算属性得到的当前城市,即:
computed: {
...mapState(['city'])
}
当在App.vue中使用<keep-alive></keep-alive>
将路由包裹起来的时候,这块的内容已经被缓存起来了,切换城市的时候也是取的缓存中的数据。
当使用keep-alive的时候,组件中会多出一个生命周期函数activated,两个生命周期函数钩子console.log一下会发现,当页面首次加载的时候mounted和activated都会执行,当在城市选择页面切换一个页面的时候,组件的mounted是不会执行的,只有activated会执行。也就是说在页面初次加载的时候,一定会发一个ajax请求,当页面重新被显示的时候activated一定会被重新执行。
我们可以判断当前显示的页面城市与上次存储的页面城市是不是同一个,不同的时候再去发一个ajax请求。
在Home组件中的data中定义一个变量lastCity,当页面被挂载的时候,对这个城市做一个保存this.lastCity = this.city
。当页面被重新激活的时候,执行以下操作:
mounted () {
this.lastCity = this.city
this.getHomeInfo()
},
activated() {
if (this.city !== this.lastCity) {
this.lastCity = this.city
this.getHomeInfo()
}
}