vue使用keep-alive缓存页面,返回页面时刷新部分数据
作用:
在vue项目中,难免会有列表页面或者搜索结果列表页面,点击某个结果之后,返回回来时,如果不对结果页面进行缓存,那么返回列表页面的时候会回到初始状态,但是我们想要的结果是返回时这个页面还是之前搜索的结果列表,这时候就需要用到vue的keep-alive技术了.
介绍:
keep-alive
是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
实际项目中,需要配合vue-router共同使用.
router-view
也是一个组件,如果直接被包在 keep-alive
里面,所有路径匹配到的视图组件都会被缓存:
<keep-alive> <router-view> <!-- 所有路径匹配到的视图组件都会被缓存! --> </router-view> </keep-alive>
生命周期执行顺序:
1、不使用keep-alive的情况:beforeRouteEnter --> created --> mounted --> destroyed
2、使用keep-alive的情况:beforeRouteEnter --> created --> mounted --> activated --> deactivated
3、使用keep-alive,并且再次进入了缓存页面的情况:beforeRouteEnter -->activated --> deactivated
路由配置
1、在项目下的router文件下的index.js进行配置
// 路由配置 export default [ { path: '/', name: 'home', component: Home, meta: { keepAlive: true // 需要被缓存 } }, { path: '/:id', name: 'edit', component: Edit, meta: { keepAlive: false // 不需要被缓存 } }
2、App.vue中改为
<keep-alive> <router-view v-if="$route.meta.keepAlive"> <!-- 这里是会被缓存的视图组件,比如 Home! --> </router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"> <!-- 这里是不被缓存的视图组件,比如 Edit! --> </router-view>
3、这时凡是被keep-alive包裹住的页面都会被缓存,如果想刷新部分内容要启用activated函数,用法同created,activated只有在被keep-alive包裹时会触发,activated函数一进入页面就触发
示例:点击邮寄地址-进入地址编辑页面-编辑后把数据传给父页面,并且父页面不刷新,只是地址更新
地址编辑页面
父页面代码:edit.vue
<van-field is-link :name="item.name" :label="item.label" :placeholder="item.label" :required=item.mandatory v-model="dataList[item.name]" @click="editAddr(item.name)" />
<script>
export default {
data() {
return {
name:'',
}
},
methods: {
editAddr(name) {
var query_data={};
query_data= {
street: this.bill_street,
pobox: this.bill_pobox,
city: this.bill_city,
state: this.bill_state,
code: this.bill_code,
country: this.bill_country,
}
this.$router.push({
path: '/address_edit',
query:query_data
});
}
},
activated() {
// 需要重新请求的写在这里
var addr_data = JSON.parse(sessionStorage.getItem('addr'));
this.bill_street = addr_data.street;
this.bill_pobox = addr_data.pobox;
this.bill_city = addr_data.city;
this.bill_state = addr_data.state;
this.bill_code = addr_data.code;
this.bill_country = addr_data.country;
var $bill_addr = this.bill_state+this.bill_city+this.bill_street;
sessionStorage.removeItem("addr");
},
}
</script>
地址编辑页面:AddressEdit.vue
<template> <div class="addr_edit"> <van-cell-group> <van-field v-model="street" rows="1" autosize label="详细地址" type="textarea" placeholder="请输入详细地址" /> </van-cell-group> <van-cell-group> <van-field v-model="pobox" label="邮政信箱" placeholder="请输入邮政信箱" /> </van-cell-group> <van-cell-group> <van-field v-model="city" label="城市" placeholder="请输入城市" /> </van-cell-group> <van-cell-group> <van-field v-model="state" label="省/州" placeholder="请输入省/州" /> </van-cell-group> <van-cell-group> <van-field v-model="code" label="邮政编码" placeholder="请输入邮政编码" /> </van-cell-group> <van-cell-group> <van-field v-model="country" label="国家" placeholder="请输入国家" /> </van-cell-group> <van-button round block type="info" @click="onSave" style="margin-top: 2px"> 确认 </van-button> </div> </template> <script> export default { data() { return { street: '', pobox:'', city:'', state:'', code:'', country:'', mode:'' }; }, created() { this.mode=this.$route.query.mode; this.street=this.$route.query.street; this.pobox=this.$route.query.pobox; this.city=this.$route.query.city; this.state=this.$route.query.state; this.code=this.$route.query.code; this.country=this.$route.query.country; }, methods: { onSave() { var data ={ 'mode':this.mode, 'street':this.street, 'pobox':this.pobox, 'city':this.city, 'code':this.code, 'state':this.state, 'country':this.country, }; sessionStorage.setItem('addr',JSON.stringify(data)); history.back(); }, }, }; </script>