加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

react router @4 和 vue路由 详解

发布时间:2020-12-15 20:39:21 所属栏目:百科 来源:网络整理
导读:react router @4 和 vue路由 本文大纲: 1、vue路由基础和使用 2、react-router @4用法 3、什么是包容性路由?什么是排他性路由? 4、react路由有两个重要的属性:children和render的区别? 5、react如何在路由里面定义一个子路由? 6、vue如何在路由里面定

react router @4 和 vue路由

本文大纲:

1、vue路由基础和使用

2、react-router @4用法

3、什么是包容性路由?什么是排他性路由?

4、react路由有两个重要的属性:children和render的区别?

5、react如何在路由里面定义一个子路由?

6、vue如何在路由里面定义一个子路由?

7、react怎么通过路由传参?

8、vue怎么通过路由传参?

9、怎么在react里拿到router对象?

10、怎么在vue里拿到router对象?

11、路由怎么回退?

12、react路由守卫?

13、vue路由守卫?

?


?

1、vue路由基础和使用

  a、大概目录

? ? ? ? ? ?

我这里建了一个router文件夹,文件夹下有index.html

?


?

  

  b、准备工作:

    npm install vue-router

    或者 yarn add vue-router

  


?

?

  c、配置

    必须要通过 Vue.use() 明确地安装路由功能:
    在你的文件夹下的 src 文件夹下的 main.js 文件内写入以下代码

import Vue from ‘vue‘

import VueRouter from ‘vue-router‘

Vue.use(VueRouter)

    附上我的代码:我是将router的内容写在了我的router文件夹下的index.html中,然后暴露出去,在main.js中引入

    router文件夹下的index.html

import Vue from ‘vue‘
import VueRouter from ‘vue-router‘
Vue.use(VueRouter)

import Home from ‘pages/Home‘
import Map from ‘components/Map‘
import Home1 from ‘components/Home1‘
import Find from ‘components/Find‘
import Mine from ‘components/Mine‘
import Type from ‘components/Type‘
import Publish from ‘components/Publish‘
import Search from ‘components/Search‘
import Success from ‘components/Success‘
import Need from ‘components/Need‘
import Position0 from ‘components/Position‘
import Like from ‘components/scrollX/Like‘
import S1 from ‘components/scrollX/1‘
import S2 from ‘components/scrollX/2‘
import Listall from ‘components/mine/Listall‘
import Listone from ‘components/mine/Listone‘
import Listchange from ‘components/mine/Listchange‘

const routes = [
    {
        path:‘/‘,redirect:‘/ho‘
    },{
        path: ‘/ho‘,redirect:‘/ho/home‘,component: Home,children: [
            {
                name: ‘home‘,path: ‘home‘,component: Home1,redirect:‘/ho/home/like‘,children :[
                    {
                        name: ‘like‘,path: ‘like‘,component: Like
                    },{
                        name: ‘2000001‘,path: ‘2000001‘,component: S1
                    },{
                        name: ‘2000022‘,path: ‘2000022‘,component: S2
                    }
                ]
            },{
                name: ‘type‘,path: ‘type‘,component: Type
            },{
                name: ‘need‘,path: ‘need‘,component: Need
            },{
                name: ‘find‘,path: ‘find‘,component: Find
            },{
                name: ‘mine‘,path: ‘mine‘,component: Mine
            }
        ]
    },{
        name: ‘search‘,path: ‘/search‘,component: Search
    },{
        name: ‘position‘,path: ‘/position‘,component: Position0
    },{
        name: ‘publish‘,path: ‘/publish‘,component: Publish
    },{
        name: ‘success‘,path: ‘/success‘,component: Success
    },{
        name: ‘listall‘,path: ‘/listall‘,component: Listall
    },{
        name: ‘listone‘,path: ‘/listone‘,component: Listone
    },{
        name: ‘listchange‘,path: ‘/listchange‘,component: Listchange
    },{
        name: ‘map‘,path: ‘/map‘,component: Map
    }
]

const router = new VueRouter({
    mode: ‘history‘,routes
})

export default router

    main.js

import Vue from ‘vue‘
import App from ‘./App.vue‘
import router from ‘./router‘

Vue.use(MintUI)
Vue.use(ElementUI);

Vue.config.productionTip = false

new Vue({
  router,render: h => h(App)
}).$mount(‘#app‘)

?


?

  d、常规使用

     <router-view></router-view>路由匹配到的组件将渲染在这里
    你可以把他理解为一个版块,比如现在有一个home页面,分为两部分,内容部分和ibar部分,如图:
    

    这五个页面共用下面的导航栏,只有导航栏上面的内容不同
    <router-view></router-view>就可以写在<Ibar></Ibar>的上面
<template>
    <div class="home">
        <router-view></router-view>
        <Ibar></Ibar>
    </div>
</template>

    那么在Ibar页面中如何切换路由呢?

<template>
    <div class="ibar">
        <router-link to="/ho/home" tag="span" active-class="active">首页</router-link>
        <router-link to="/ho/type" tag="span" active-class="active">类别</router-link>
        <router-link to="/ho/need" tag="span" active-class="active">需求</router-link>
        <router-link to="/ho/find" tag="span" active-class="active">发现</router-link>
        <router-link to="/ho/mine" tag="span" active-class="active">我的</router-link>
    </div>
</template>

    注意:此处的tag=“span”代表这个按钮是个span标签,你可以写样式的时候直接写span标签的样式即可

       此处的active-class="active"代表点击哪个按钮哪个按钮高亮

    

    此时我们详细看一下router文件夹下的index.js

//引入vue  

import Vue from
‘vue‘

//引入路由
import VueRouter from ‘vue-router‘

//把路由挂载到vue上
Vue.use(VueRouter)
//引入我各个路由对应的component组件
import Home from
‘pages/Home‘ import Map from ‘components/Map‘ import Home1 from ‘components/Home1‘ import Find from ‘components/Find‘ import Mine from ‘components/Mine‘ import Type from ‘components/Type‘ import Publish from ‘components/Publish‘ import Search from ‘components/Search‘ import Success from ‘components/Success‘ import Need from ‘components/Need‘ import Position0 from ‘components/Position‘ import Like from ‘components/scrollX/Like‘ import S1 from ‘components/scrollX/1‘ import S2 from ‘components/scrollX/2‘ import Listall from ‘components/mine/Listall‘ import Listone from ‘components/mine/Listone‘ import Listchange from ‘components/mine/Listchange‘
const routes
= [ {

     //path是路由的路径
path:
‘/‘,

     //redirect代表重定向,因为当前路径‘/‘并没有对应的组件,所以需要重定向到其他路由页面
     redirect:
‘/ho‘ },

     //当不需要重定向的时候,需要component写上当前路由对应的组件页面
component: Home,

     //有些路由还有子路由,需要用到children[],
     //当访问的时候,<router-link>的属性to的时候要把所有的父组件都带上
     //如:此处的/ho/home/like
children: [ { name:
‘home‘,component: Map } ] const router = new VueRouter({

//此处设置mode为history,即不带#号,在处理数据的时候会更方便一些
    mode: ‘history‘,

//ES6的写法,即routes:routes的简写,当key和value名字一样时,可简写
routes })
//把你创建的路由暴露出去,使得main.js可以将其引入并使用
export
default router

    引申1:

    路由有一个meta属性

    可以给该路由挂载一些信息

    设置一些自己title、显示隐藏、左右滑动的方向之类的

meta: {
      title: "HelloWorld",要现实的title
      show: true               设置导航隐藏显示
}

    使用的时候:this.$route.meta.show

    <Bottom v-show="this.$route.meta.show"></Bottom>

?

    引申2:

    动态路由

{
    path:"/two/:id",component:Two,}

    获取数据this.$route.params.动态路由的名字

    此处是:this.$route.params.id

?

    引申3:

    路由别名alias

{ 
    path: ‘/a‘,component: A,alias: ‘/b‘ 
}
//  /a 的别名是 /b
//意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a
//就像用户访问 /a 一样
//简单的说就是给 /a 起了一个外号叫做 /b,但是本质上还是 /a

?


?

2、react-router @4用法

  a、大概目录

  ? ? ?

不需要像vue那样麻烦的用到一个单独的文件夹,react只需要在index.js中部分配置即可

?


?

  b、准备工作

   ? yarn add react-router-dom

?

   index.js中

   ??import { BrowserRouter } from ‘react-router-dom‘

   ??

? ? ? ? ? <BrowserRouter>
? ? ? ? ?   <App />
? ? ? ? ? </BrowserRouter>
    这样App内部组件都可以使用
?

 
  c、使用
  ? ? ?同样是上面那个例子,写法不一样:
import React,{ Component } from ‘react‘;
import {Bar} from ‘components/common/ibar‘

import ShopDetail from ‘pages/shopDetail/shopDetail‘

import NodeDe from ‘pages/noteDetail/NodeDe‘

import Car from ‘pages/car/Car‘

import Admin from ‘pages/admin/Admin‘

import Admin1 from ‘pages/admin/Admin1‘

import GoodDetail from ‘pages/goodDetail/goodDetail‘

import { Route,Switch,Redirect } from ‘react-router-dom‘

class App extends Component {
  render() {
    return (

    //这里为什么要用Switch包裹呢?
    //<Switch>是唯一的因为它仅仅只会渲染一个路径
<Switch>

     //Redirect代表重定向,如果加了exact代表精准匹配
<Redirect exact from="/" to="/home"></Redirect> <Route path=‘/home‘ component={Bar}/> <Route path="/shopDetail/:shopId/:shopName/:shopNote/:shopPic" component={ShopDetail} /> <Route path=‘/noteDetail/:noteId‘ component={NodeDe} /> <Route path=‘/goodDetail/:goodId/:shopId‘ component={GoodDetail} /> <Route path=‘/car‘ component={Car} /> <Route path=‘/admin‘ component={Admin}/> <Route path=‘/admin1/:phone‘ component={Admin1}/> </Switch> ); } } export default App;

?

    当点击哪里需要跳转的时候,在标签外面包一个<Link to= ‘ 路由路径 ‘ ></Link>    ? ? ?

? ? ? ? ? ??

    动态路由/xxx/:xx,如上图

    

    引申1:HashRouter和BrowserRouter

      它们两个是路由的基本,就像盖房子必须有地基一样

      我们需要将它们包裹在最外层,我们只要选择其一就可以了。

      现在讲它们的不同:

     HashRouter

     ? 如果你使用过react-router2或3或者vue-router

     ? 你经常会发现一个现象就是url中会有个#,

? ? ? ? ? ? ? ? ?例如localhost:3000/#

? ? ? ? ? ? ? ? ?HashRouter就会出现这种情况,它是通过hash值来对路由进行控制

? ? ? ? ? ? ? ? ?如果你使用HashRouter,你的路由就会默认有这个#。

       ??

    ? ?BrowserRouter

? ? ? ? ? ? ? ? ?很多情况下我们则不是这种情况,我们不需要这个#

     ? 因为它看起来很怪,这时我们就需要用到BrowserRouter。

?

    引申2:Link和NavLink的选择

      两者都是可以控制路由跳转的,不同点是NavLink的api更多,更加满足你的需求。

    ? ? ?Link:主要api是to,to可以接受string或者一个object,来控制url

      

  

     ?NavLink:它可以为当前选中的路由设置类名、样式以及回调函数等。

  ? ? ? ? ? ?

?

    引申3:withRouter高阶组件

//引入withRouter
import { Link,withRouter } from
‘react-router-dom‘ //代码结尾暴露的时候,把要暴露的组件包裹在withRouter中,做成一个高阶组件,
//将react-router 的 history,location,match 三个对象传入
//将组件包一层withRouter,就可以拿到需要的路由信息
//获取路由信息的时候
this.props.location
withRouter(GoodDetail)

withRouter(connect(mapState,mapDispatch)(GoodDetail))

?

?


?

?

3、什么是包容性路由?什么是排他性路由?

  

  包容性路由:

    如果路由有/food 和 /food/1 那么在匹配 /food 的时候两个都能匹配到

    react就是典型的包容性路由

    所以react需要引入Switch标签,把路由变成排他性的

  

  排他性路由:?

    只要匹配成功一个就不会往下面进行匹配了

    vue是排他性路由

    匹配从上到下,匹配到一个即止

?


?

4、react路由有两个重要的属性:children和render,这两个有什么区别?

  a、Route 可以写行间render,render={()=>{return }}
?
  b、也可以写行间children={()={return }}
?
  c、不管匹配与否children都执行
?
  d、render优先级比children高

  


?
5、react如何在路由里面定义一个子路由?
?
  a、引入在需要子路由的页面引入Route标签  
?
   <Route path=‘/noteDetail/home‘ component={NodeDe} />

  b、举个??(糖炒栗子,我的爱,为什么我自己做的??都那么难吃???)

?

    

?

    我们在home页面里(左边一溜的父组件)该点击的地方

export const Home = () => (
  <ul>
    <li>
      <NavLink to=‘/home‘ exact activeStyle ={selectedStyle}>首页</NavLink>
    </li>
    <li>
      <NavLink to=‘/about‘ activeStyle ={selectedStyle}>关于我们</NavLink>
    </li>
    <li>
      <NavLink to=‘/event‘ activeStyle ={selectedStyle}>企业事件</NavLink>
    </li>
    <li>
      <NavLink to=‘/product‘ activeStyle ={selectedStyle}>公司产品</NavLink>
    </li>
    <li>
      <NavLink to=‘/us‘ activeStyle ={selectedStyle}>联系我们</NavLink>
    </li>
  </ul>
)

?    我们在home页面里(左边一溜的父组件)设置内容应该不同的地方

      <Redirect exact from="/" to="/home"></Redirect>
      <Route path=‘/home‘ exact component={Home}/>
      <Route path=‘/about‘ component={About}/>
      <Route path=‘/event‘ component={Event}/>
      <Route path=‘/product‘ component={Product}/>    
      <Route path=‘/us‘ component={Us}/>    

?

    我们在关于我们页面该点击的地方

export const AboutMenu = () => (
  <ul className="about-menu">
    <li>
      <NavLink to=‘/about‘ exact activeStyle ={selectedStyle}>公司简介</NavLink>
    </li>
    <li>
      <NavLink to=‘/about/history‘ activeStyle ={selectedStyle}>公司历史</NavLink>
    </li>
    <li>
      <NavLink to=‘/about/services‘ activeStyle ={selectedStyle}>公司服务</NavLink>
    </li>
    <li>
      <NavLink to=‘/about/location‘ activeStyle ={selectedStyle}>企业位置</NavLink>
    </li>
  </ul>
)

    我们在关于我们页面该实现内容不同的地方

      <Route path=‘/about‘ exact component={Company}/>
      <Route path=‘/about/history‘ component={History}/>
      <Route path=‘/about/services‘ component={Services}/>
      <Route path=‘/about/location‘ component={Location}/>

?

    由此便实现了react子路由

?


?

?

6、vue如何在路由里面定义一个子路由?

  给父路由加一个?children:[]

  参考我的<1.d>的代码

const routes = [
    {

     //path是路由的路径

        path:‘/‘,     //redirect代表重定向,因为当前路径‘/‘并没有对应的组件,所以需要重定向到其他路由页面
    
        redirect:‘/ho‘
    },     //当不需要重定向的时候,需要component写上当前路由对应的组件页面

        component: Home,     //有些路由还有子路由,需要用到children[],
     //当访问的时候,<router-link>的属性to的时候要把所有的父组件都带上
     //如:此处的/ho/home/like

        children: [

      //子路由写在children数组里,仍旧以对象的形式

{ name:
‘home‘,component: Map } ] const router = new VueRouter({ //此处设置mode为history,即不带#号,在处理数据的时候会更方便一些 mode: ‘history‘,//ES6的写法,即routes:routes的简写,当key和value名字一样时,可简写 routes }) //把你创建的路由暴露出去,使得main.js可以将其引入并使用 export default router

?


?

7、react怎么通过路由传参?

  a、通配符传参(刷新页面数据不丢失)

//在定义路由的时候

<Route path=‘/path/:自己起个名字‘ component={Path}/>


//在路由点击跳转的时候

<Link to="/path/你要传的参数">通配符</Link>


//另一个页面接收传来的参数

this.props.match.params.你起的名字

  

  ? ? ?举个??

  ? ? ?

   ? 另一个页面接收值的时候:

        this.props.match.params.id

?

  b、query传参(刷新页面数据丢失)

//路由定义

<Route path=‘/query‘ component={Query}/>

//跳转的时候
var query = {
        pathname: ‘/query‘,query: ‘我是通过query传值 ‘
}

<Link to={query}>query</Link>

//另一个页面使用的时候

this.props.location.query

这里的this.props.location.query === ‘我是通过query传值‘

?

  c、state传参(刷新页面数据丢失,同query差不多,只是属性不一样,而且state传的参数是加密的,query传的参数是公开的)?

//Route定义

<Link to={state}>state</Link>

//使用的时候

    var state = {
        pathname: ‘/state‘,state: ‘我是通过state传值‘
    }
    <Route path=‘/state‘ component={State}/>

//另一个页面获取值的时候

this.props.location.state

这里的this.props.location.state === ‘我是通过query传值‘

?

  d、路由?传参数

? ? ? ? ? ?

   ? 此处的foodmenu通过路由?后面传参数

   ? 在另一个页面的this.props.location.search可以获取到 "?id=6"?

?


?

8、vue怎么通过路由传参?

  a、通配符传参数

//在定义路由的时候

{
     path: ‘/describe/:id‘,name: ‘Describe‘,component: Describe
}

//在使用的时候

this.$router.push({
       path: `/describe/${id}`,})

//接收页面获取值

this.$route.params.id

?

  b、params传参,跳转的时候不会显示在url上

//在定义路由的时候

{
     path: ‘/describe‘,component: Describe
}

//在使用的时候

this.$router.push({
      name: ‘Describe‘,params: {
            id: id
      }
})

//接收页面获取值

this.$route.params.id

?

  c、query传参,传餐的时候在url显示? key=value & key=value

//在定义路由的时候

   {
     path: ‘/describe‘,component: Describe
   }

//在使用的时候

 this.$router.push({
          path: ‘/describe‘,query: {
            id: id
          }
 })

//接收页面获取值
this.$route.query.id

?


?

?

9、怎么在react里拿到router对象?

  import withRouter 并且 export组件的时候,用withRouter把组件包起来

//引入withRouter
import {
    Link,withRouter
} from ‘react-router-dom‘

//代码结尾暴露的时候,把要暴露的组件包裹在withRouter中,做成一个高阶组件,
//将react-router 的 history,match 三个对象传入
//将组件包一层withRouter,就可以拿到需要的路由信息
//获取路由信息的时候this.props.location
withRouter(GoodDetail)

withRouter(connect(mapState,mapDispatch)(GoodDetail))

?


?

?

10、怎么在vue里拿到router对象? 

//在使用的时候

 this.$router.push({
          path: ‘/describe‘,query: {
            id: id
          }
 })

//接收页面获取值
this.$route.query.id

?


?

11、路由怎么回退?

  a、vue:this.$router.back(-1)

  b、react:this.props.history.goback()

?


?

?

12、react路由守卫?

  a、在之前的版本中,React Router 也提供了类似的?onEnter?钩子,但在 React Router 4.0 版本中,取消了这个方法。

  b、那么在react中如果我们也需要路由守卫怎么办?比如在跳转路由前需要判断用户是否登录?如果登录才可以进行跳转,否则没有权限

  c、

//下面是我的实现方式,
//首先,准备一份路由表,
//包含了路由的地址,组件以及是否需要权限校验:

import { HomePage } from ‘../pages/home/home.page‘;
import { LoginPage } from ‘../pages/login/login.page‘;
import { ErrorPage } from ‘../pages/error/error.page‘;

interface routerConfigModel {
    path:string,component?:any,auth?:boolean
}

export const routerConfig:routerConfigModel[] = [
    {
        path:‘/‘,component:HomePage,auth:true,},{
        path:‘/home‘,{
        path:‘/login‘,component:LoginPage,{
        path:‘/404‘,component:ErrorPage
    }
];

//将 auth 设置为 true,表示该路由需要权限校验。
//然后,定义 Router 组件,该组件是经过高阶组件包装后的结果:

import * as React from ‘react‘;
import { HashRouter,Switch } from ‘react-router-dom‘;
import { FrontendAuth } from ‘../components/frontend-auth/frontend-auth.component‘
import { routerConfig } from ‘./router.config‘

export class Router extends React.Component{
    render(){
        return(
            <HashRouter>
                <Switch>
                    <FrontendAuth config={routerConfig} />
                </Switch>
            </HashRouter>
        );
    }
}


//所有的路由跳转,都交给 FrontendAuth 高阶组件代理完成。
//下面是 FrontendAuth 组件的实现:

import * as React from ‘react‘;
import { Route,Redirect } from ‘react-router-dom‘;
import { propsModel } from ‘./frontend-auth.model‘

export class FrontendAuth extends React.Component<any,propsModel>{
    render(){
        const { location,config } = this.props;
        const { pathname } = location;
        const isLogin = localStorage.getItem(‘__config_center_token‘)
        
        // 如果该路由不用进行权限校验,登录状态下登陆页除外
        // 因为登陆后,无法跳转到登陆页
        // 这部分代码,是为了在非登陆状态下,访问不需要权限校验的路由
        
        const targetRouterConfig = config.find((v:any) => v.path === pathname);
        if(targetRouterConfig && !targetRouterConfig.auth && !isLogin){
            const { component } = targetRouterConfig;
            return <Route exact path={pathname} component={component} />
        }

        if(isLogin){
            // 如果是登陆状态,想要跳转到登陆,重定向到主页
            if(pathname === ‘/login‘){
                return <Redirect to=‘/‘ />
            }else{
                // 如果路由合法,就跳转到相应的路由
                if(targetRouterConfig){
                    return <Route path={pathname} component={targetRouterConfig.component} />
                }else{
                    // 如果路由不合法,重定向到 404 页面
                    return <Redirect to=‘/404‘ />
                }
            }
        }else{
            // 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆
            if(targetRouterConfig && targetRouterConfig.auth){
                return <Redirect to=‘/login‘ />
            }else{
                // 非登陆状态下,路由不合法时,重定向至 404
                return <Redirect to=‘/404‘ />
            }
        }
    }
}

//以及对应的 Model:

export interface propsModel {
    config:any[],}

//页面上的路由跳转,都由 FrontendAuth 高阶组件代理了,
//在 Switch 组件内部,不再是 Route 组件,
//而只有一个 FrontendAuth 组件。


//FrontendAuth 组件接收一个名为 config 的 Props,这是一份路由表。
//同时,由于 FrontendAuth 组件放在了 Switch 组件内部,React Router 还自动为 FrontendAuth 注入了 location 属性,
//当地址栏的路由发生变化时,就会触发 location 属性对象上的 pathname 属性发生变化,
//从而触发 FrontendAuth 的更新(调用 render 函数)。

//FrontendAuth 的 render 函数中,
//根据 pathname 查找到路由表中的相关配置,
//如果该配置中指定了无需校验,就直接返回相应的 Route 组件。
//如果查找到的配置需要进行校验,再根据是否登陆进行处理,具体可以查看代码中的注释。

总结一下,实现路由守卫需要考虑到以下的问题:

未登录情况下,访问不需要权限校验的合法页面:允许访问
登陆情况下,访问登陆页面:禁止访问,跳转至主页
登陆情况下,访问除登陆页以外的合法页面:允许访问
登陆情况下,访问所有的非法页面:禁止访问,跳转至 404
未登录情况下,访问需要权限校验的页面:禁止访问,跳转至登陆页
未登录情况下,访问所有的非法页面:禁止访问,跳转至 404
    

?

13、vue路由守卫

  a、beforeEach

  全局守卫

(每个路由调用前都会触发,根据from和to来判断是哪个路由触发)

const router = new VueRouter({ ... })

router.beforeEach((to,from,next) => {
  // ...
})

//每个守卫功能都有三个参数:
//to: Route:导航到的目标Route对象
//from: Route:当前路线被导航离开
//next: Function:必须调用此函数来解析钩子
//    next():继续前进到管道中的下一个钩子。如果没有留下挂钩,则确认导航。

//    next(false):中止当前导航。如果浏览器URL已更改(由用户手动或通过后退按钮),则会将其重置为from路径的URL 。

//    next(‘/‘)或next({ path: ‘/‘ }):重定向到其他位置。当前导航将中止,并将启动一个新导航。你可以通过任何位置对象next,它允许您指定类似的选项replace: true,name: ‘home‘在使用任何选项router-link的to道具或router.push

//    next(error):(2.4.0+)如果传递给的参数next是一个实例Error,导航将被中止,错误将传递给通过注册的回调router.onError()。

`

  

    举个??

import Vue from ‘vue‘;
import Router from ‘vue-router‘;
import LoginPage from ‘@/pages/login‘;
import HomePage from ‘@/pages/home‘;
import GoodsListPage from ‘@/pages/good-list‘;
import GoodsDetailPage from ‘@/pages/good-detail‘;
import CartPage from ‘@/pages/cart‘;
import ProfilePage from ‘@/pages/profile‘;

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: ‘/‘,// 默认进入路由
      redirect: ‘/home‘   //重定向
    },{
      path: ‘/login‘,name: ‘login‘,component: LoginPage
    },{
      path: ‘/home‘,name: ‘home‘,component: HomePage
    },{
      path: ‘/good-list‘,name: ‘good-list‘,component: GoodsListPage
    },{
      path: ‘/good-detail‘,name: ‘good-detail‘,component: GoodsDetailPage
    },{
      path: ‘/cart‘,name: ‘cart‘,component: CartPage
    },{
      path: ‘/profile‘,name: ‘profile‘,component: ProfilePage
    },{
      path: ‘**‘,// 错误路由
      redirect: ‘/home‘   //重定向
    },]
});

// 全局路由守卫
router.beforeEach((to,next) => {
  console.log(‘navigation-guards‘);
  // to: Route: 即将要进入的目标 路由对象
  // from: Route: 当前导航正要离开的路由
  // next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

  const nextRoute = [‘home‘,‘good-list‘,‘good-detail‘,‘cart‘,‘profile‘];
  let isLogin = global.isLogin;  // 是否登录
  // 未登录状态;当路由到nextRoute指定页时,跳转至login
  if (nextRoute.indexOf(to.name) >= 0) {  
    if (!isLogin) {
      console.log(‘what fuck‘);
      router.push({ name: ‘login‘ })
    }
  }
  // 已登录状态;当路由到login时,跳转至home 
  if (to.name === ‘login‘) {
    if (isLogin) {
      router.push({ name: ‘home‘ });
    }
  }
  next();
});

export default router;

?

?

  b、beforeResolve(2.5.0新增)

  全局解析守卫

类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用router.beforeEach

?

  c、afterEach

  全局后置钩子

router.afterEach((to,from) => {
  // ...
})

//不会接受next函数也
//也不会改变导航本身

?

  d、beforeEnter  

  路由独享的守卫

const router = new VueRouter({
  routes: [
    {
      path: ‘/foo‘,component: Foo,beforeEnter: (to,next) => {
        // ...
      }
    }
  ]
})

//与全局前置守卫的方法参数是一样的

?

  e、

? ? 组件内的守卫

  • beforeRouteEnter
  • beforeRouteUpdate?(2.2新增)
  • beforeRouteLeave
const Foo = {
  template: `...`,beforeRouteEnter (to,next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },beforeRouteUpdate (to,next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },

  //离开守卫通常用来禁止用户在还未保存修改前突然离开。导航该可以通过来取消
beforeRouteLeave (to,next) {
// 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` } }next(false)

  

//beforeRouteEnter守卫不能访问this,
//因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。

//不过,可以你传通过一个回调给next来访问组件实例。
//在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

beforeRouteEnter (to,next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 全局调用的beforeEach守卫。
  4. 在重用的组件里调用beforeRouteUpdate守卫(2.2+)。
  5. 在路由配置里调用beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用beforeRouteEnter
  8. 调用全局的beforeResolve守卫(2.5+)。
  9. 导航被确认。
  10. 全局调用的afterEach钩子。
  11. 触发DOM更新。
  12. 创建33用实例好的调用beforeRouteEnter守卫中传给next的回调函数。

  

  

以上。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读