需求
有两个页面, 一个列表页一个详情页. 在列表页点击查看详情按钮跳转至详情页, 看完详情跳转回列表页时, 要保留之前的筛选条件.
这个需求在中后台管理系统和移动端应用都很常见. 用户选择了半天筛选条件, 看完其中一个详情后, 再跳转回查询页看下一项的详情, 结果发现筛选条件和列表全部恢复默认值... 估计要崩溃, 所以还有必要保留筛选条件的
实现方案
vuex
起初想的时: 用 vuex 全局存储筛选条件, 每次查询都从 vuex 中拿筛选条件即可. 这种方法是可以, 但是实现麻烦. 万一筛选条件多或者复杂, 例如单选多选全选, 写 mutation 方法改变 state 都得搞半天.
故放弃 vuex
keep-alive
官方用法介绍:
<keep-alive> 包裹动态组件时, 会缓存不活动的组件实例, 而不是销毁它们. 和 <transition> 相似,<keep-alive> 是一个抽象组件: 它自身不会渲染一个 DOM 元素, 也不会出现在父组件链中.
当组件在 <keep-alive> 内被切换, 它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行.
简单的说, 就是用 keep_alive 包裹着组件, 这个组件就会被缓存, 我们切换页面时这个组件会保留在内存中, 若我们缓存列表页, 那跳转详情页再跳回列表页, 就会从内存中直接读取列表页, 这样筛选条件仍然是之前的. 完美解决需求
项目中用到了 vue-router, 所以在 App.vue 结合里缓存 router-view 即可.
- <transition name="move" mode="out-in">
- <keep-alive>
- <router-view v-if="$route.meta.alive"></router-view>
- </keep-alive>
- </transition>
- <transition name="move" mode="out-in">
- <router-view v-if="!$route.meta.alive"></router-view>
- </transition>
实现筛选条件保留后, 还没做完..
万一跳转详情页后, 列表中某一项改变了, 而内存中缓存的列表页并未更新, 再跳转回列表页展示的就不是最新数据. 所以我们跳转回去必须得再调用一次查询接口获取最新数据, 更新列表
这时候 avtivated 就发挥作用了. 切换回列表页时, 会触发 activated 钩子. 像 mounted 一样, 我们复制 mounted 的代码过来即可
- activated(){
- search()
- }
到此, 跳转页面保持筛选条件的需求就完美解决啦.
用到的知识点:
keep-alive
v-if
路由 router-view + route.meta
生命周期
总结
在用 keep-alive 的时候, 还遇到了个坑. 有 include 和 exclude 这两个 API.
include - 字符串或正则表达式. 只有名称匹配的组件会被缓存.
exclude - 字符串或正则表达式. 任何名称匹配的组件都不会被缓存.
- <keep-alive include="a,b">
- <router-view></router-view>
- </keep-alive>
我这样写并没有生效, 原因可能是需要所有的组件都配置 name 属性. 等有时间在验证一下. 暂时使用 route.meta+v-if 缓存相应的组件
来源: http://www.jianshu.com/p/17594c971ad6