reactrouter4路由钩子_react router @4 和 vue路由 详解(全)

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

export const Home = () =>(

  • 首页

  • 关于我们

  • 企业事件

  • 公司产品

  • 联系我们

)

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

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

export const AboutMenu = () =>(

  • 公司简介

  • 公司历史

  • 公司服务

  • 企业位置

)

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

由此便实现了react子路由

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

给父路由加一个 children:[]

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

const routes =[

{//path是路由的路径

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

redirect:'/ho'},

{

path:'/ho',

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

component: Home,//有些路由还有子路由,需要用到children[],

//当访问的时候,的属性to的时候要把所有的父组件都带上

//如:此处的/ho/home/like

children: [

//子路由写在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= newVueRouter({//此处设置mode为history,即不带#号,在处理数据的时候会更方便一些

mode: 'history',//ES6的写法,即routes:routes的简写,当key和value名字一样时,可简写

routes

})//把你创建的路由暴露出去,使得main.js可以将其引入并使用

exportdefault router

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

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

//在定义路由的时候

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

通配符

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

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

举个

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

this.props.match.params.id

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

//路由定义

//跳转的时候

var query ={

pathname:'/query',

query:'我是通过query传值 '}query

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

this.props.location.query

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

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

//Route定义

state

//使用的时候

var state ={

pathname:'/state',

state:'我是通过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',

name:'Describe',

component: Describe

}//在使用的时候

this.$router.push({

name:'Describe',

params: {

id: id

}

})//接收页面获取值

this.$route.params.id

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

//在定义路由的时候

{

path:'/describe',

name:'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,location,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',

component:HomePage,

auth:true,

},

{

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(

);

}

}//所有的路由跳转,都交给 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{

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

}if(isLogin){//如果是登陆状态,想要跳转到登陆,重定向到主页

if(pathname === '/login'){return

}else{//如果路由合法,就跳转到相应的路由

if(targetRouterConfig){return

}else{//如果路由不合法,重定向到 404 页面

return

}

}

}else{//非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆

if(targetRouterConfig &&targetRouterConfig.auth){return

}else{//非登陆状态下,路由不合法时,重定向至 404

return

}

}

}

}//以及对应的 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 = newVueRouter({ ... })

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= newRouter({

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, from, 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();

});

exportdefault router;

b、beforeResolve(2.5.0新增)

全局解析守卫

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

c、afterEach

全局后置钩子

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

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

d、beforeEnter

路由独享的守卫

const router = newVueRouter({

routes: [

{

path:'/foo',

component: Foo,

beforeEnter: (to, from, next)=>{//...

}

}

]

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

e、

组件内的守卫

beforeRouteEnter

beforeRouteUpdate(2.2新增)

beforeRouteLeave

const Foo ={

template: `...`,

beforeRouteEnter (to, from, next) {//在渲染该组件的对应路由被 confirm 前调用

//不!能!获取组件实例 `this`

//因为当守卫执行前,组件实例还没被创建

},

beforeRouteUpdate (to, from, next) {//在当前路由改变,但是该组件被复用时调用

//举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,

//由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。

//可以访问组件实例 `this`

},

//离开守卫通常用来禁止用户在还未保存修改前突然离开。导航该可以通过next(false)来取消

beforeRouteLeave (to, from, next) {//导航离开该组件的对应路由时调用

//可以访问组件实例 `this`

}

}

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

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

beforeRouteEnter (to, from, next) {

next(vm=>{//通过 `vm` 访问组件实例

})

}

完整的导航解析流程

导航被触发。

在失活的组件里调用离开守卫。

全局调用的beforeEach守卫。

在重用的组件里调用beforeRouteUpdate守卫(2.2+)。

在路由配置里调用beforeEnter。

解析异步路由组件。

在被激活的组件里调用beforeRouteEnter。

调用全局的beforeResolve守卫(2.5+)。

导航被确认。

全局调用的afterEach钩子。

触发DOM更新。

创建³³用实例好的调用beforeRouteEnter守卫中传给next的回调函数。

以上。

你可能感兴趣的:(reactrouter4路由钩子_react router @4 和 vue路由 详解(全))