在开发vue的项目中有遇到了这样一个需求:一个视频列表页面,展示视频名称和是否收藏,点击进去某一项观看,可以收藏或者取消收藏,返回的时候需要记住列表页面的页码等状态,同时这条视频的收藏状态也需要更新, 但是从其他页面进来视频列表页面的时候不缓存这个页面,也就是进入的时候是视频列表页面的第一页
一句话总结一下: pageAList->pageADetail->pageAList, 缓存pageAList, 同时该视频的收藏状态如果发生变化需要更新, 其他页面->pageAList, pageAList不缓存
在网上找了很多别人的方法,都不满足我们的需求
然后我们团队几个人捣鼓了几天,还真的整出了一套方法,实现了这个需求
实现后的效果
无图无真相,用一张gif图来看一下实现后的效果吧!!!
操作流程:
首页->pageAList, 跳转第二页 ->首页-> pageAList,页码显示第一页,说明从其他页面进入pageAList, pageAList页面没有被缓存
pageAList, 跳转到第三页,点击视频22 -> 进入视频详情页pageADetail,点击收藏,收藏成功,点击返回 -> pageAList显示的是第三页,并且视频22的收藏状态从未收藏变成已收藏,说明从pageADetail进入pageAList,pageAList页面缓存了,并且更新了状态
说明:
二级缓存: 也就是从A->B->A,缓存A
三级缓存:A->B->C->B->A, 缓存A,B 因为项目里面绝大部分是二级缓存,这里我们就做二级缓存,但是这不代表我的这个缓存方法不适用三级缓存,三级缓存后面我也会讲如何实现
实现二级缓存
用vue-cli2的脚手架搭建了一个项目,用这个项目来说明如何实现
先来看看项目目录
删除了无用的components目录和assets目录,新增了src/pages目录和src/store目录, pages页面用来存放页面组件, store不多说,存放vuex相关的东西,新增了server/app.js目录,用来启动后台服务
1. 前提条件
项目引入vue,vuex, vue-router,axios等vue全家桶
引入element-ui,只是为了项目美观,毕竟本人懒癌晚期,不想自己写样式
在config/index.js里面配置前端代理
引入express,启动后台,后端开3003端口,给前端提供api支持 来看看服务端代码server/app.js,非常简单,就是造了30条数据,写了3个接口,几十行文件直接搭建了一个node服务器,简单粗暴解决数据模拟问题,会mock用mock也行
const express = require('express') // const bodyParser = require('body-parser') const app = express() let allList = Array.from({length: 30}, (v, i) => ({ id: i, name: '视频' + i, isCollect: false })) // 后台设置允许跨域访问 // 前后端都是本地localhost,所以不需要设置cors跨域,如果是部署在服务器上,则需要设置 // app.all('*', function (req, res, next) { // res.header('Access-Control-Allow-Origin', '*') // res.header('Access-Control-Allow-Headers', 'X-Requested-With') // res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS') // res.header('X-Powered-By', ' 3.2.1') // res.header('Content-Type', 'application/json;charset=utf-8') // next() // }) app.use(express.json()) app.use(express.urlencoded({extended: false})) // 1 获取所有的视频列表 app.get('/api/getVideoList', function (req, res) { let query = req.query let currentPage = query.currentPage let pageSize = query.pageSize let list = allList.slice((currentPage - 1) * pageSize, currentPage * pageSize) res.json({ code: 0, data: { list, total: allList.length } }) }) // 2 获取某一条视频详情 app.get('/api/getVideoDetail/:id', function (req, res) { let id = Number(req.params.id) let info = allList.find(v => v.id === id) res.json({ code: 0, data: info }) }) // 3 收藏或者取消收藏视频 app.post('/api/collectVideo', function (req, res) { let id = Number(req.body.id) let isCollect = req.body.isCollect allList = allList.map((v, i) => { return v.id === id ? {...v, isCollect} : v }) res.json({code: 0}) }) const PORT = 3003 app.listen(PORT, function () { console.log('app is listening port' + PORT) })
2. 路由配置