Home >Web Front-end >JS Tutorial >vue-router project practice (detailed tutorial)
vue-router is the official routing library of Vue.js. This article mainly introduces the practical summary of the vue-router project. Friends who need it can refer to it
Let’s talk about the vue project today{ vue,vue-router,component
} vue-router, one of the three great generals. As one of our important practices for front-end and back-end separation, router helps us complete page jumps between SPA applications.
And, with third-party libraries like axios, we can implement interceptor functions that work with the background interface.
For a small project, it is enough that the router folder contains a router.js.
However, when we have a lot of pages, we need to divide them into Come out two files: one defines our routes and components, and the other instantiates the components and mounts the route to the vue instance.
I won’t go into details about the basic usage. You can check out the official website of vue-router. If you read it carefully, there will definitely be no problem with basic usage.
1. Why does my routing not work?
A very important point here is when we construct an instance of VueRouter Sometimes, there is a problem with the parameters passed in.
import routes from '@/router/router' const router = new VueRouter({ routes // (ES6语法)相当于 routes: routes }) new Vue({ router }).$mount('#app')
If what you introduce here is not routes, you have to write it in the following way.
import vRoutes from '@/router/router' const router = new VueRouter({ routes :vRoutes }) new Vue({ router }).$mount('#app')
2. Implement lazy loading of components based on webpack in routing
For our vue projects, we basically use webpack for packaging Yes, if there is no lazy loading, the packaged files will be abnormally large, resulting in a white screen on the homepage and serious delays, which is not conducive to the user experience. Lazy loading can be used to divide the page, and webpack packages different components into many Small js file. Load asynchronously when needed to optimize the user experience. In other words, only one or two of 100 users may enter some pages, so why spend traffic on it.
import App from '@/App.vue' const index = r => require.ensure([], () => r(require('@/pages/index/index')), 'index') export default [{ path: '/', component: App, children: [ { path: '/index', name:'index', component: index }] }]
If a component contains nested routes, we can also package the two routes into a js chunk.
// 这两条路由被打包在相同的块中,访问任一路由都会延迟加载该路由组件 const orderUser= r => require.ensure([], () => r(require('@/pages/order/user')), 'order') const payRecord= r => require.ensure([], () => r(require('@/pages/order/payRecord')), 'order')
3.Router mode
For browsers, our router is divided into two modes.
1.hash mode (default)
According to the basic structure of a uri, the hash mode is processed in a basic URI fragment. If we put aside SPA, the more common application scenario is that when we are building a PC mall, there will be tab switching such as product details, comments, and product parameters. We can use the a tag with the ID, and add a little movement. The special effects are very good.
This is also the routing method used by router by default. However, this method has a drawback, that is, when connecting to a third-party payment, we pass in a URL to the third-party payment as a callback address, but after the payment is completed, some third-party payment will transfer our # As an interception symbol, only the url content before the first # symbol is retained, and the corresponding callback parameters are added later. As a result, after the payment is completed, it cannot jump to the corresponding payment page
Incoming url:
http://xx.xx.com/#/pay/123
Address after callback:
http://xx.xx.com/pay/123?data=xxxxx%xxxx
2.history mode
There is also a history mode. It uses h5's history.pushState to complete the URL jump. The advantage of using this method to handle jumps is that the URL is no different from what we usually see. If compared with the hash mode, there is no #. However, when using history mode, we also need to do corresponding processing in the background, because if we directly access an address, such as http://www.xxxx.com/user/id, if the backend is not configured, then The client will return a 404 page.
4.router-link is in the loop this.Parameter name=undefined
##b988a8fd72e5e0e42afffd18f951b277The component is our view layer The jump component that needs to be used. It replaces what the 3499910bf9dac5ae3c52d5ede7383485 tag needs to do, and helps us do a lot more. Whether it is h5 history mode or hash mode, its performance behavior is consistent, so when you want to switch routing mode, or downgrade to use hash mode in IE9, no changes are required. In HTML5 history mode, router-link will guard the click event so that the browser will not reload the page. When you use the base option in HTML5 history mode, all to attributes do not need to be written (base path). But when we use router-link in a v-for loop, generally speaking, what we need to get are the values in the loop, which can be obtained through the defined item.xxx. If we need to get a value we defined in data, do we get it through this.foo? Or should I retrieve it through foo? Or is it okay? Here, we cannot get it through this.foo, because this here no longer points to the instance of vue, but points to [object Window]. So if you use this.foo to retrieve it, it is actually undefined.<router-link tag="li" :to="{path:`/user/${item.userID}`}" v-for="(item, index) in userList" :key="index"> //含有固定的值 <p>{{this.foo}}</p> <p>{{foo}}</p> </router-link> data(){ return { foo:'bar', } }
4. Using vue-router with axios
初次接触拦截器这个概念是在java中,通过拦截器,我们可以对用户的登录状态进行更加粒度的操作。而对于一个SPA的应用来说,没有了后台路由的介入,我们就需要在前端实现一套自己的登录状态的管理机制。
最直观的一点就是,通过用户的token来判断用户是否登录?
router.beforeEach((to, from, next) => { const NOW = new Date().getTime(); if (to.matched.some(r => r.meta.requireAuth)) { if(NOW > store.state.deadLine){ store.commit('CLEAR_USERTOKEN') } if (store.state.message.login === true) { next(); } else { next({ path: '/login', query: {redirect: to.fullPath} }) } } else { next(); } })
上面的代码中,我们通过vue-router中的全局守卫,在导航触发的时候大致做了如下几件事:
(1)判断导航的页面是否需要登录
(2)超过登录持久期限,清除持久化的登录用户token
(3)没有超过登录期限,判断是否登录状态
(4)没登录,重定向到登录页面
但是,仅仅这样是不够的。因为用户直接不正常注销而直接后台运行网页是很正常的事情,这就导致虽然token是存在的,但是对于后台而言,这个token是无效的,过期的了。所以,我们需要axios配合后台给出的状态码来完善我们的拦截器。
import router from '@/router/routes' axios.interceptors.response.use( success => { switch (success .code) { case -100: router.replace({ path: 'login', query: {redirect: router.currentRoute.fullPath} }) console.warn('注意,登录已过期!') break; } return success; }, error => { switch (error.code) { case 404: console.warn('请求地址有误或者参数错误!') break; } return Promise.reject(error.response.data) });
通过后端给到的登录过期状态码,这里以-100为例,我们可以用axios的响应拦截器实现,当我们的token过期的时候,我们将页面重定向到登录页面去。
5.巧用replace替换push
在项目中,我有的同事就是一直this.$router.push(...)
,从开始push到结尾。
碰到有的页面,比如说,在选择地址的时候需要知道用户当前所在的城市,如果没有的话,就是重定向到城市列表页面去手动选取。选择完成以后再回到选择地址的页面,如果一直使用push的话,点击选择地址的后退时,就会回退到城市列表页。然后造成页面间的死循环。
这里如果使用replace来操作就没有什么问题了,问题就是我们不应该让城市列表页出现在我们的浏览历史里面。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
The above is the detailed content of vue-router project practice (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!