本篇我们将使用keep-alive 优化前面我们的两个网页的性能。
先新建一个分支 city-keepalive, pull 下来,在新分支上写代码。
network 面板下,选择 XHR .会发现,每次跳转到城市选择页面,会请求一次city.json;每次跳转到主页,会请求一次index.json.
而每次这样是,没有必要的。
vue 提供了keep-alive 标签。它框住的内容,被加载过一次后,就会把里面的内容放在内存中。下次,再使用时,就不需要重新渲染、执行钩子函数,只需要从内存中读出来即可。
app.vue 代码
<template>
<div id="app">
<keep-alive>
<router-view/>
</keep-alive>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
/*font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;*/
/*margin-top: 60px;*/
}
</style>
这样子之后,再次访问主页面和城市选择页面,就不会重新去请求数据了。
但有一个问题,当在城市选择页面,换了一个城市后,主页的内容应该要随之改变。应该去请求数据的。
首先,我们修改Home.vue。在ajax 请求的时候加上城市名。如下。
<template>
<div>
<home-header></home-header>
<home-swiper :list="swiperList"></home-swiper>
<home-icons :list="iconList"></home-icons>
<home-recommend :list="recommedList"></home-recommend>
<home-weekend :list="weekendList"></home-weekend>
</div>
</template>
<script>
import HomeHeader from './components/Header.vue'
import HomeSwiper from './components/Swiper.vue'
import HomeIcons from './components/Icons.vue'
import HomeRecommend from './components/Recommend.vue'
import HomeWeekend from './components/Weekend.vue'
import axios from 'axios'
import { mapState } from 'vuex'
export default {
name: 'Home',
components: {
HomeHeader,
HomeSwiper,
HomeIcons,
HomeRecommend,
HomeWeekend
},
data () {
return {
swiperList: [],
iconList: [],
recommedList: [],
weekendList: []
}
},
computed: {
...mapState(['city'])
},
methods: {
getHomeInfo () {
axios.get('/api/index.json?city=' + this.city)
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
if (res.ret && res.data) {
const data = res.data
this.swiperList = data.swiperList
this.iconList = data.iconList
this.recommedList = data.recommendList
this.weekendList = data.weekendList
}
}
},
mounted () {
this.getHomeInfo()
}
}
</script>
然后,在使用keep-alive 时,组件会多一个生命周期函数 activated 。
我们通过activated 函数 与一个lastCity 变量,实现更改当前城市时,首页才会发送ajax请求。代码如下。
Home.vue
<template>
<div>
<home-header></home-header>
<home-swiper :list="swiperList"></home-swiper>
<home-icons :list="iconList"></home-icons>
<home-recommend :list="recommedList"></home-recommend>
<home-weekend :list="weekendList"></home-weekend>
</div>
</template>
<script>
import HomeHeader from './components/Header.vue'
import HomeSwiper from './components/Swiper.vue'
import HomeIcons from './components/Icons.vue'
import HomeRecommend from './components/Recommend.vue'
import HomeWeekend from './components/Weekend.vue'
import axios from 'axios'
import { mapState } from 'vuex'
export default {
name: 'Home',
components: {
HomeHeader,
HomeSwiper,
HomeIcons,
HomeRecommend,
HomeWeekend
},
data () {
return {
lastCity: '',
swiperList: [],
iconList: [],
recommedList: [],
weekendList: []
}
},
computed: {
...mapState(['city'])
},
methods: {
getHomeInfo () {
axios.get('/api/index.json?city=' + this.city)
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
if (res.ret && res.data) {
const data = res.data
this.swiperList = data.swiperList
this.iconList = data.iconList
this.recommedList = data.recommendList
this.weekendList = data.weekendList
}
}
},
mounted () {
this.lastCity = data.city
console.log('mounted')
this.getHomeInfo()
},
activated () {
console.log('activated')
if (this.lastCity !== this.city) {
this.lastCity = this.city
this.getHomeInfo()
}
}
}
</script>
Done! 城市选择页面做完了。
可以提交合并了。