目录
1-个人中心
1.1-个人中心路由注册
1.2-拆分二级路由组件
1.3-动态渲染我的订单页面
2-导航守卫优化
2.1-用户未登录导航守卫优化
2.2-路由独享
2.3-组件内守卫
3-懒加载
3.1-图片懒加载
3.2-路由懒加载
4-map文件处理
需求:当用户点击支付成功组件页面的,查看订单时,需要跳转路由到个人中心-我的订单页面,展示当前用户的订单,并且动态渲染用户的订单信息。
将开发好的静态路由组件,注册到路由信息中,之前配置的全部是一级路由信息,这里为了实战二级路由操作,我们特意将个人中心静态组件进行拆分,配置二级路由信息。这里就将我的订单和团购订单拆分出来成二级路由组件。
在center目录中新建目录myOrder和groupOrder文件夹,抽取相关html结构过去。然后在路由中配置文件中配置相关路由。
配置跳转到/center是直接重定向到我的订单路由组件中。
在父组件中添加这个配置:
当进入到个人中心页面组件时,默认展示的是我的订单,所以在我的订单组件页面加载时,需要向获取我的订单数据。
由于一个订单对应的明细是数组,对应多个商品,所以我们动态渲染的时候,需要合并相关信息,:rowspan="order.orderDetailList.length" v-show="index==0" 需要用到rowspan属性,合并的行数,循环遍历只展示index=0的;
我的订单组件页面还需要展示分页信息,这里就使用我们之前自己开发的全局分页组件,当用户点击下面的分页信息时,需要动态获取分页数据。
用户未登录时,有些组件页面是不能去的,比如支付页面,我的订单页面,需要统一进行拦截...拦截到登录页面,如果用户登录后,需要重定向到之前的页面。
比如浏览器直接敲center路由(配置了center默认到center/myOrder),判断用户未登录,跳转到登录页面,但是路径上带有redirect=%2Fcenter%2FmyOrder,我们拿到这个参数,用户登录后直接跳转到这个组件页面。
router.beforeEach(async (to, from, next) => {
let hasToken = store.state.user.token;
//用户信息
let hasNickName = store.state.user.nickName;
//用户登录
if (hasToken) {
if (to.path == "/login") { //用户登录了,不能去login
next('/home');
} else {
if (hasNickName) {//用户登陆了,而且还有用户信息【去的并非是login】
next();
} else {//用户登陆了,但是没有用户信息
try {
//发请求获取用户信息以后再放行
await store.dispatch('getUserInfo');
next();
} catch (error) {//获取用户信息失败,要么就是token失效了,要么服务器挂了
//token失效:【通过调用退出登录action】本地清空数据、服务器的token通知服务器清除
await store.dispatch('logout');
//回到登录页,让用户重新登录
next('/login');
}
}
}
} else {
//用户未登录:不能进入/trade、/pay、/paysuccess、/center、/center/myorder /center/teamorder
let toPath = to.path;
if (toPath.indexOf('trade') != -1 || toPath.indexOf('pay') != -1 || toPath.indexOf('center') != -1) {
next('/login?redirect=' + toPath);
} else {
next();
}
}
});
实际项目中我们只能指定从哪个页面跳转到什么页面,比如我们只能从/shopCart组件页面跳转到/trade页面等逻辑。
next()
: 就是放行。进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 就是在当面页面。中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
在组件页面编写守卫
const Foo = {
template: `...`,
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
比如我们将上面/paySuccess在src\router\routes.js中的路由独享守卫删掉,我们在paySuccess组件内实现,同样可行。
为了提高用户使用系统的体验性以及相关性能,我们可以使用防抖,节流,按需引入等等措施,这里我们先学习一下懒加载。
比如商品详情页面,我们需要展示商品的图片,当用户网络不好的时候,我们可以先展示默认图片,等服务端数据返回我们就展示服务端的图片,这就是所谓的图片懒加载。
vue-lazyload - npm
安装插件版本使用1.3.3
npm install vue-lazyload@^1.3.3 --save --force
比如我们将:src标签变更为v-lazy;
路由懒加载:当用户访问的时候,加载对应组件进行展示。
路由懒加载 | Vue Router
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
之前写法:
路由懒加载写法:
map文件的作用:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。 有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。也就是说map文件相当于是查看源码的一个东西。如果不需要定位问题,并且不想被看到源码,就把productionSourceMap 置为false,既可以减少包大小,也可以加密源码。