1、在main.js中添加
import ctpRouter from '@/ares-ui-extend/CtpRouter'; Vue.use(ctpRouter, router);
2、添加相应的代码
在src的目录下添加 ares-ui-extend 的文件夹
ares-ui-extend 文件夹的下面添加CtpRouter,CtpRouter下面为:
ctp-router.css内容为:
/* 动画样式 */ .fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0; } .sild-leave-active { transition: all 1.5s; } .sild-enter-active { transition: all .4s; } /* .sild-enter /* .fade-leave-active below version 2.1.8 { transform:translate3d(100%, 0, 0); } .sild-leave-to /* .fade-leave-active below version 2.1.8 { transform:translate3d(-100%, 0, 0); } */ .sild1-leave-active { transition: all .4s; } .sild1-enter-active { transition: all .4s; } /* .sild1-enter /* .fade-leave-active below version 2.1.8 { transform:translate3d(-100%, 0, 0); } .sild1-leave-to /* .fade-leave-active below version 2.1.8 { transform:translate3d(100%, 0, 0); } */ .sild-enter /* .fade-leave-active below version 2.1.8 */ { transform: translate3d(2rem, 0, 0); opacity: 0; } .sild-leave-to /* .fade-leave-active below version 2.1.8 */ { transform: translate3d(-2rem, 0, 0); opacity: 0; } .sild1-enter /* .fade-leave-active below version 2.1.8 */ { /* transform: translate3d(-2rem, 0, 0); */ opacity: 0; } .sild1-leave-to /* .fade-leave-active below version 2.1.8 */ { transform: translate3d(2rem, 0, 0); opacity: 0; }
index.js 的内容为:
/* 拦截重写vue路由,提供滑动动画效果,记录页面位置 */ import Nav from './nav'; import './ctp-router.css'; function CtpRouter(Vue) { Vue.prototype.$ctpRouter = { tn: 'slide', // 动画名 keepAlives: [], // keepAlive存储 }; this.stack = []; this.PAGEKEY = new Date().getTime(); this.createPageKey = () => { this.PAGEKEY += 1; return this.PAGEKEY.toString(); }; this.findStackIndex = pageKey => this.stack.findIndex(item => item === pageKey); this.pushStack = (pageKey) => { const index = this.findStackIndex(pageKey); this.stack.slice(0, index + 1); this.stack.push(pageKey); }; this.clearStack = (pageKey) => { if (pageKey) { for (let i = 0; i < this.stack.length; i += 1) { if (pageKey === this.stack[i]) { this.stack.splice(i, 1); break; } } } else { this.stack = []; } }; this.rewriteRouter = (router) => { ['push', 'replace'].forEach((method) => { const func = router[method].bind(router); router[method] = (location, onComplete, onAbort) => { const obj = {}; if (typeof location !== 'object') { obj.path = location; } else { Object.assign(obj, location); } if (!obj.query) { obj.query = {}; } if (method === 'push') { obj.query.$page_key = this.createPageKey(); this.pushStack(obj.query.$page_key); } if (method === 'replace') { obj.query.$replace = true; } func(obj, onComplete, onAbort); }; }); }; this.setKeepAlive = (router) => { const routes = router.options.routes; if (routes && routes.length > 0) { routes.forEach((route) => { const meta = route.meta; if (meta && meta.keepAlive) { Vue.prototype.$ctpRouter.keepAlives.push(route.name); } }); } }; this.setTransition = (from, to) => { const fromIndex = this.findStackIndex(from.query.$page_key); const toIndex = this.findStackIndex(to.query.$page_key); if (fromIndex < toIndex) { // enter Vue.prototype.$ctpRouter.tn = 'sild'; } else if (fromIndex > toIndex) { // leave Vue.prototype.$ctpRouter.tn = 'sild1'; } else { Vue.prototype.$ctpRouter.tn = 'none'; // replace则不做任何动画 } }; this.storeFromScrollTop = (vm, from) => { const scrollContainer = vm.$refs.scrollContainer; if (scrollContainer && from.meta) { from.meta.scrollTop = scrollContainer.scrollTop; } }; // 跳转时,设置to页面的已记录的高度(来自于storeFromScrollTop) this.reStoreToScrollTop = (vm, to) => { const scrollContainer = vm.$refs.scrollContainer; if (scrollContainer && to.meta && to.meta.scrollTop) { scrollContainer.scrollTop = to.meta.scrollTop; } }; } export default (Vue, router) => { const ctpRouter = new CtpRouter(Vue); ctpRouter.setKeepAlive(router); ctpRouter.rewriteRouter(router); Vue.component(Nav.name, Nav); Vue.mixin({ beforeRouteEnter(to, from, next) { if (!to.query.$page_key) { // 首次进入的时候没有$page_key const obj = Object.assign({}, to); obj.replace = true; obj.query.$page_key = ctpRouter.createPageKey(); ctpRouter.pushStack(obj.query.$page_key); next(obj); } else { next((vm) => { ctpRouter.reStoreToScrollTop(vm, to); }); } }, beforeRouteLeave(to, from, next) { if (to.query.$replace) { to.query.$page_key = from.query.$page_key; delete to.query.$replace; const obj = Object.assign({}, to); obj.replace = true; next(obj); return; } ctpRouter.storeFromScrollTop(this, from); // 记录离开时的位置 ctpRouter.setTransition(from, to); // 设置动画 next(); }, }); };
nav.vue的内容为:
<template> <transition :name="$ctpRouter.tn"> <keep-alive :include="$ctpRouter.keepAlives"> <slot></slot> </keep-alive> </transition> </template> <script> export default { name: 'ctp-router', }; </script>
3、用法:在定义路由的时候在meta中添加 keepAlive 的布尔值,为true则启用缓存记录页面位置,为false则不启用缓存。例子:
{ path: '/Home/notice/notice_center', name: 'notice_center', component: resolve => require(['@/pages/Home/notice/notice_center.vue'], resolve), meta: { moduleName: 'notice_center', title: '消息中心', keepAlive: false }, routerLevel: 2, }
4、总结:
ares-ui-extend 和 CtpRouter 这俩文件夹的名字,自己可以随便更改,ares-ui是公司自有的框架,所以最好是起一个别的名字。其他代码可以参考着拿来直接用。
目的就是缓存组件数据,返回上一页的时候,记录之前的操作位置,这样统一封装之后,移动端的项目有这样的需求,就直接改变路由里面meta的keepAlive值即可。
标签:动画,vue,obj,ctpRouter,leave,fade,active,query,页面 From: https://www.cnblogs.com/smile-fanyin/p/18201529