1、业务需求
不管是移动端H5页面还是web端页面,通常会有这样一个需求,当从列表页面A跳转到详情页面B后,再从详情页面B跳转到列表页面A时,需要将A页面恢复到跳转到详情页面B之前的状态,这样的需求对于非单页面来说实现起来很容易,但是对于非单页面来说并不是那么的容易,本文主要讲在vue项目中如何实现。
2、主要用到的技术
vuex和vue的keep-alive组件
3、具体实现
(1)首先要在项目中安装并引入vuex
cnpm install --save vuex // 安装
(2)在项目src目录下创建store文件夹,及相应的getters、actions和mutations的文件等,项目截图如下
index.js文件具体代码
import Vue from 'vue'
import Vuex from 'vuex'
import * as getters from './getters'
import * as actions from './actions'
import mutations from './mutations'
Vue.use(Vuex)
const state = {
keepAlive: true // 默认为true
};
export default new Vuex.Store({
state,
getters,
mutations,
actions
})
actions.js代码如下
import * as types from './mutation-types'
// 注:action里可执行异步函数,mutation里不能执行异步函数
export const setKeepAlive = ({commit},keepAlive)=>{
commit(types.SET_KEEPALIVE,keepAlive)
}
getters.js代码如下
export const keepAlive = state => state.keepAlive
mutation-types.js文件如下
export const SET_KEEPALIVE = 'SET_KEEPALIVE'
mutations.js代码如下
import * as types from './mutation-types'
export default {
[types.SET_KEEPALIVE](state,keepAlive){
state.keepAlive = keepAlive
},
}
main.js引入
import "babel-polyfill"
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'
Vue.config.productionTip = false
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI,{size:'small'});
import './assets/scss/reset.scss'
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
(3) app.vue组件
<template>
<div id="app">
<div v-if="keepAlive">
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
<div v-if="!keepAlive">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'App',
computed:{
keepAlive(){
return this.$store.getters.keepAlive
}
},
methods:{
},
}
</script>
<style>
#app {
height: 100%;
}
</style>
(4) 在项目src目录下的components目录下创建keepAlive文件夹,及相应的list.vue、detail.vue和otherMenu.vue,项目截图如下
list.vue文件
<template>
<div id='list'>
<h1>我是列表页</h1>
<br>
<el-input v-model="input" placeholder="请输入内容"></el-input>
<br> <br>
<el-button @click="goToDetail()">去详情页</el-button>
<br> <br>
<el-button @click="goToOther()">去其他页面</el-button>
</div>
</template>
<script>
export default {
data() {
return {
input: ''
}
},
created() {
this.$store.commit('SET_KEEPALIVE',true)
},
methods: {
goToOther(){
this.$store.commit('SET_KEEPALIVE',false)
this.$router.push({name: 'otherMenu'})
},
goToDetail(){
this.$store.commit('SET_KEEPALIVE',true)
this.$router.push({name: 'detail'})
},
},
}
</script>
<style lang="scss">
#list {
box-sizing: border-box;
padding: 50px;
}
</style>
detail.vue文件
<template>
<div id='detail'>
<h1>我是详情页</h1>
<el-button @click="reBack">返回列表页面</el-button>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
reBack(){
this.$router.back()
}
}
}
</script>
<style lang="scss">
#detail {
box-sizing: border-box;
padding: 50px;
}
</style>
otherMenu.vue文件
<template>
<div id='otherMenu'>
<h1>我是其他页面</h1>
<br>
<el-input v-model="input" placeholder="请输入内容"></el-input>
<br> <br>
<el-button @click="goToList()">去列表页</el-button>
</div>
</template>
<script>
export default {
data() {
return {
input: ''
}
},
created() {
},
methods: {
goToList(){
this.$router.push({name: 'list'})
}
}
}
</script>
<style lang="scss">
#otherMenu {
box-sizing: border-box;
padding: 50px;
}
</style>
(5)router.js文件
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/list',
name: 'list',
component: () => import('../components/keepAliveTest/list.vue'),
},
{
path: '/detail',
name: 'detail',
component: () => import('../components/keepAliveTest/detail.vue')
},
{
path: '/otherMenu',
name: 'otherMenu',
component: () => import('../components/keepAliveTest/otherMenu.vue'),
},
]
})
export default router
PS:欢迎加入vue技术交流群(864583465)进行更多问题的探讨,你的问题将是我们大家共同进步的关键