vue路由

vue路由的理解

1路由理解

一个路由(route)就是一组映射关系(key-value),多个路由需要路由器(router)进行管理。前端路由中key是路径,value是组件

作用:设定访问路径,并将路径和组件映射起来(就是用于局部刷新页面,不需要请求服务器来切换页面)

2路由传参

有两种传参方式,第一种query传参 第二种params传参

query传参

1.字符串写法直接写在路径中拼接 ?+参数 ,

2.对象写法 ,把路径单独写,数据单独写

数据传递根据的是路由路径

<!-- 跳转并携带query参数,to的字符串写法 -->
<router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link>
				
<!-- 跳转并携带query参数,to的对象写法 -->
<!-- name:'detail' 可以写路由的name 也可以直接写路径 -->
<router-link 
	:to="{
		path:'/home/message/detail',
		query:{
		   id:666,
        title:'你好'
		}
	}"
   >跳转</router-link>

组件接收数据用的是$route.query

<template>
<div>
 <h3>信息编号:{{ $route.query.id }}</h3>
 <h3>信息标题:{{ $route.query.title }}</h3>
</div>
</template>

<script>
export default {
name: "Msgdata",
};
</script>

<style>
</style>

当有多个需要传递的参数时,总在模板中写 $route.query, 肯定是不好的,这时候就需要路由中接收并包装一下

还可以在路由设置中进行获取然后再传递到组件 可以用到props,写在组件的路由中

routes:[
	{
		path:'/about',
		component:About,
	},
	{
		path:'/home',
		component:Home,
		children:[ //通过children配置子级路由
			{    
             name:'news'
				path:'news', //此处一定不要写:/news
				component:News
			},
			{
             name:'message'
				path:'message',//此处一定不要写:/message
				component:Message,
             children: [
                  {
                         path: 'msgdata',
                         component: Msgdata,
                     //在这里接收一下传来的参数,然后包装一下再传给组件
                         props($route){
                            return {id:$route.query.id,title:$route.query.title}
                              }     
			        }
		        ]
	}
]

子组件接收

<template>
<div>
 <h3>信息编号:{{ id }}</h3>
 <h3>信息标题:{{ title }}</h3>
</div>
</template>

<script>
export default {
name: "Msgdata",
props: ["id", "title"],
};
</script>

<style>
</style>

r o u t e r 和 router和 routerroute的区别可去目录9查看

params传参

1.直接路径传递参数

在路径中直接加 引号内的东西都会当成字符处理,所以给to加上冒号让他解析成表达式,但是表达式没有以斜杠开头的,所以加上` 模板引号 又变成了字符串,然后用${}配合模板字符串。

<router-link :to="`/home/news/shownews/${n.id}/${n.name}`">
{{ n.name }}
</router-link> 

2.方式写成对象形式

必须写name不可以用path作为路径

<router-link
    :to="{
      // 用params传递参数时用到他的对象写法中不可使用 path:'路径'
      name: 'shownews',
      params: {
        id: n.id,
        name: n.name,
      },
    }"
  >
    {{ n.name }}
  </router-link>

组件使用时和query相似

<ul>
<!-- query里面写数据 -->
<li>编号{{ $route.params.id }}</li>
<li>姓名{{ $route.params.name }}</li>
</ul>

如果有很多数据需要用时,可以借助路由包装一下,只需要props的值为true

name: 'shownews',
// params 写法先在路径中占位
path: 'shownews/:id/:name',
component: ShowNews,
// props的第二种写法 props为布尔值,会接收所有params参数 以props的形式传递给Detail组件
props: true

子组件接收

<template>
<ul>
<!-- query里面写数据 -->
<li>编号{{ id }}</li>
<li>姓名{{ name }}</li>
</ul>
</template>

<script>
export default {
name: "ShowNews",
props: ["id", "title"],
};
</script>

params传参可以理解为 ajax 中的 post 请求方式,参数都是不可见的,但是有一个弊端,就是当页面刷新了是获取不到参数值。用 query 来传参,这种方式可以理解为是 ajax 中的 get 方法,参数是直接在 url 后面添加的,参数是可见的,可以解决页面刷新参数消失问题

3.声明式与编程式路由导航

点击链接切换组件,这就是导航,也可以称为路径导航。导航又分为两种:声明式和编程式

vue中的导航

1.声明式导航:我们在网页中点击链接实现网页的切换;在Vue项目中点击切换组件,这都属于声明式导航

2.编程式导航:通过调用API方法实现导航的方式叫做编程式导航,比如在普通的网页中我们会去掉用location.href跳转到新页面

vue-router中有五种编程式导航API:

this.$router.push('Hash地址')

跳转到指定Hash地址,且增加一条历史记录
this.$router.replace('Hash地址')

跳转到指定Hash地址,且替换掉当前历史记录
this.$router.go('Number')

在浏览器历史记录中前进或者后退(1、-1......)

如果超出上限的话,则原地不动

在实际开发中前进或者后退一个以上页面是不常使用的,所以vue-router为我们提供了以下俩种方法用来前进后退一个页面:

this.$router.back()

后退一个历史页面

this.$router.forward()

前进一个历史页面

react中的导航

1.声明式导航 【Link,NavLink】

声明式导航自己主要用到的是react中的两个路由组件【Link、NavLink】。其中Link组件的导航方式和HMTL中的a标签类似,在react将虚拟DOM渲染成真实DOM后,Link组件也被渲染成了a标签。

react中的路由懒加载方式(link方式)

import React, { Component,lazy,Suspense } from 'react'//导入了路由懒加载模块
import { Route,Redirect,Link} from 'react-router-dom'
import Login from '../Login/index'
const lazyComponent = lazy(() => import('../lazyComponent')); //使用路由懒加载的方式加载组件
export default class World extends Component {
render() {
return (
<div className='worldFrame'>
  {/* 使用路由 */}
  <ul>
    <li>
      <h1>
      {/*使用Link跳转,同时携带参数ID*/}
      <Link to={`/login/${id}`} className='red'>跳转到Login</Link>
      <br />
      <Link to="/lazyComponent" className='red'>跳转到路由懒加载组件</Link>
      </h1>
    </li>
  </ul>
  <hr /> 
  <ul>
    <li>
    {/*渲染路由组件Login到该位置,同时接收到路由参数ID*/}
        <Route path='/login/:id' component={Login}></Route>
        {/*重定向*/}
        <Redirect to='/'></Redirect>
    </li>
    <li>
    {/*使用路由懒加载的模块,路由组件未加载出来前会以Loading字符显示在页面中*/}
      <Suspense fallback={<h1 style={{color:'skyblue'}}>Loading...</h1>}>
        <Route path="/lazyComponent" component={lazyComponent}></Route>
      </Suspense>
    </li> 
  </ul>
  <br />
</div>
)
}
}

NavLink方式相当于Link的加强版,主要的属性有:

activeClassName(string):设置选中样式,默认值为active
activeStyle(object):当元素被选中时,为此元素添加样式
exact(bool):为true时,只有当导致和完全匹配class和style才会应用
strict(bool):为true时,在确定为位置是否与当前URL匹配时,将考虑位置pathname后的斜线
isActive(func)判断链接是否激活的额外逻辑的功能

2.编程式导航 【props, useHistory() , Route】

利用已注册路由组件的props

import { Route, Redirect, Switch, BrowserRouter } from 'react-router-dom';
import { Component } from 'react';
import Aside from './views/Aside';
import AsideTwo from './views/Aside/AsideTwo';
import AsideThree from './views/Aside/AsideThree';

export default class App extends Component {
render(){

return (
<div className="App">
  <BrowserRouter>
    <aside className='content'>
      <Switch>
      	{/*注册路由组件*/}
        <Route path="/aside" component={Aside}></Route>
        <Route path="/aside2" component={AsideTwo}></Route>
        <Route path="/aside3" component={AsideThree}></Route>
        {/*重定向*/}
        <Redirect to='/aside'></Redirect>
      </Switch>
  </BrowserRouter>
</div>
)
}
}


子组件通过接收父组件传参实现跳转

//函数组件
import './index.sass'
export default function AsideTwo(props){
const changeLink = ()=>{
// console.log('@@@@@',props)
props.history.push('/aside')
}
return(
<>
<h1>主要视图区</h1>
<h3>主要展示区2</h3>
<button onClick={changeLink}>跳转到/aside</button>
</>
)
}

//类组件
import { Component } from 'react'
import './index.sass'
export default class AsideThree extends Component{
changLink = ()=>{
this.props.history.push('/aside')
console.log('MMMM',this.props);
}
render(){
return(
<>
<h1>主页面视图</h1>
<h3>主要展示区1</h3>
<button onClick={this.changLink}>跳转到/aside</button>
</>
)
}
}

这种方法缺点就是使用时需要在已注册的路由组件中使用,如果该组件不是路由组件,则props对象中将不会有需要使用的路由参数(如果父组件没有给子组件传参,props会是一个空对象)

在没有注册路由的组件中使用编程式导航

利用useHistory() 钩子(hook)来做函数式组件的编程式导航(该钩子函数只能用于函数组件)

import { useHistory } from 'react-router';//导入useHistory钩子
import { Button } from 'antd';
export default function Header(){
let history = useHistory() //将useHistory()钩子赋值给history方便使用
let programmingLink = function(){
history.push('/home')//点击按钮后使用push方法跳转到对应的路由位置
}

return(
<div className='header'>
<div className='btns'>
  <Button type="primary" onClick={programmingLink} ghost>Dashed</Button>
</div>
</div>
)
}

在类式组件中需要进行编程式跳转【使用Route组件的render属性】

import { Component } from 'react'
import { Route } from 'react-router'
export default class Footer extends Component {
render () {
return (
<>
  <Route render={({ history }) => (<button onClick={() => { history.push('/changLink') }}>点击更换路由</button>)} />
</>
)
}
}

该方法push进去的路由需要是已经在Route组件中注册的路由,如果路由未注册,则无法跳转

4路由守卫

路由守卫的作用 : 对路由进行权限管理,必须符合条件才能访问。

路由守卫有三种: 全局守卫、独享守卫、组件内守卫

全局守卫

有三个参数to:去哪个路径,from:从哪个路径里来,next:是个函数调用的时候next()放行

// 配置在实例对象外 初始化时调用,每次发生路由变化前调用
router.beforeEach((to,from,next)=>{
	console.log('beforeEach',to,from)
	if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
		if(localStorage.getItem('school') === 'atguigu'){ //权限控制的具体规则
			next() //放行
		}else{
			alert('暂无权限查看')
			// next({name:'guanyu'})
		}
	}else{
		next() //放行
	}
})

//全局后置守卫:初始化时执行、每次路由切换后执行
router.afterEach((to,from)=>{
	console.log('afterEach',to,from)
	if(to.meta.title){ 
		document.title = to.meta.title //修改网页的title
	}else{
		document.title = 'vue_test'
	}
})

独享守卫

放在需要进行权限设置的路由里面,参数语法和全局一样 当访问这个路径前才执行beforeEnter()

beforeEnter(to,from,next){
	console.log('beforeEnter',to,from)
	if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
		if(localStorage.getItem('school') === 'atguigu'){
			next()
		}else{
			alert('暂无权限查看')
			// next({name:'guanyu'})
		}
	}else{
		next()
	}
}

组件守卫

放在组件里和methods,components同级别 ,必须是通过路由规则进入该组件才可以调用

beforeRouteEnter(),beforeRouteLeave()


//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
},
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值