Vue Router

0 路由原理

路由器的两种工作模式:

hash模式:(toB)

        地址中永远带着#号,不美观,兼容性较好(#及其后面的内容就是hash值,hash值不会带给服务器);

        若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。

history模式:(toC)

        兼容性较差;路径会提交给后台。

        应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。

hash :window.onhashchange监听路由改变。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>hash test</title>
</head>
<body>
    <p>hash test</p>
    <button id="btn1">修改 hash</button>

    <script>
        //3. hash 变化,包括:
        // a. JS 修改 url
        // b. 手动修改 url 的 hash
        // c. 浏览器前进、后退
        window.onhashchange = (event) => {
            console.log('old url', event.oldURL)
            console.log('new url', event.newURL)

            console.log('hash:', location.hash)
        }

        //1. 页面初次加载,获取 hash
        document.addEventListener('DOMContentLoaded', () => {
            console.log('hash:', location.hash)
        })

        //2. JS 修改 url
        document.getElementById('btn1').addEventListener('click', () => {
            location.href = '#/user'
        })
    </script>
</body>
</html>

 history:window.onpopstate监听路由改变。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>history API test</title>
</head>
<body>
    <p>history API test</p>
    <button id="btn1">修改 url</button>

    <script>
        //1. 页面初次加载,获取 path
        document.addEventListener('DOMContentLoaded', () => {
            console.log('load', location.pathname)
        })

        //2. 打开一个新的路由
        // 【注意】用 pushState 方式,浏览器不会刷新页面
        document.getElementById('btn1').addEventListener('click', () => {
            const state = { name: 'page1' }
            console.log('切换路由到', 'page1')
            history.pushState(state, '', 'page1') // 重要!!
        })

        //3. 监听浏览器前进、后退
        window.onpopstate = (event) => { // 重要!!
            console.log('onpopstate', event.state, location.pathname)
        }

        // 需要 server 端配合,可参考
        // https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90
    </script>
</body>
</html>

1 基本使用

v3.5.2

<router-link>: 路由链接, 生成路由链接
<router-view>: 路由视图, 显示当前路由组件
<keep-alive>: 缓存路由组件对象

main.js

import Vue from 'vue';
import router from './router';//index.js可以简写

new Vue({
    el: '#app',
    router,
    components: { App },
    template: '<App/>'
});

router/index.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import {routes} from './routes.js';

Vue.use(VueRouter);
const router = new VueRouter({
    mode: 'history',//该模式兼容性差
    routes
});
export default router;

router/routes.js

export const routes=[
  { 
    path: '/', 
    redirect: '/home,//重定向
  },
  { 
    path: '/home', 
    component: Home,
    name:'MyHome',//命名路由 
  },
  { 
    path: '/about', 
    component: About 
  },
]

hello.vue

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!--使用 router-link 组件进行导航:本质是a链接;激活时类名是router-link-active(默认) -->
    <router-link to="/home" active-class="active">Go to Home</router-link>
    <router-link :to="{name:'MyAbout',params:{id:1}}" replace>Go to About</router-link>
  </p>
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

2 嵌套路由

export const routes=[
  { 
    path: '/', 
    redirect: '/home',
  },
  { 
    path: '/home', 
    component: Home,
    redirect: '/home/profile',//嵌套路由重定向
    children: [//嵌套路由规则
      {
        path: 'profile',
        component: UserProfile,
      },
      {
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
  { 
    path: '/about', 
    component: About 
  },
]

3 路由传参

$route:路由参数对象:包含params/query/path/fullpath(query参数)/meta

$router:路由器对象:包含控制路由跳转的方法(push/replace/back)

3.0 路由的props配置 

作用:让路由组件更方便的收到参数。

{
	name:'xiangqing',
	path:'detail/:id',
	component:Detail,

	//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
	// props:{a:900}

	//第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
	// props:true
	
	//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
	props(route){
		return {
			id:route.query.id,
			title:route.query.title
		}
	}
}

3.1 params

<router-link to="/about/68">Go to About</router-link>

export const routes=[
  { 
    path: '/', 
    redirect: '/home',
  },
  { 
    path: '/home', 
    component: Home 
  },
  { 
    path: '/about/:mid',//使用占位符声明接收params参数 
    component: About,
    props:true,//开启后,组件中可直接访问mid,需要声明接收 
  },
]

const {mid} = this.$route.params

3.2 query 

   <!-- 传递参数 -->
   <!-- 跳转并携带query参数,to的字符串写法 -->
   <router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link>
   				
   <!-- 跳转并携带query参数,to的对象写法 -->
   <router-link 
   	:to="{
   		path:'/home/message/detail',
   		query:{
   		   id:666,
           title:'你好'
   		}
   	}"
   >跳转</router-link>


   <!-- 接收参数 -->
   $route.query.id

4 编程式导航

this.$router.push(‘/home/’+id)//增加一条历史记录

this.$router.replace({name:'MyAbout',params:{id:1}})//替换当前历史记录

this.$router.go()

this.$router.back()

this.$router.forward()

5 导航守卫

导航守卫可以控制路由的访问权限。

5.1 全局守卫

全局前置守卫:初始化时执行、每次路由切换前执行(案例:登录后,才可以访问主页

全局后置守卫:初始化时执行、每次路由切换后执行(修改网页title)

const router = new VueRouter()

// 全局前置守卫:三个参数
router.beforeEach(function(to, from, next) {
  if (pathArr.indexOf(to.path) !== -1) {//判断当前要导航的路由是否需要权限
    const token = localStorage.getItem('token')
    if (token) {//有权限
      next()//有token,放行
    } else {
      next('/login')//无token,强制登录
    }
  } 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'
   	}
})

export default router

注意:next(false)表示不允许跳转

5.2 独享守卫

在路由配置上定义路由独享守卫 

const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: (to, from) => {
      // reject the navigation
      return false
    },
  },
]

5.3 组件内守卫

   //进入守卫:通过路由规则,进入该组件时被调用
   beforeRouteEnter (to, from, next) {
   },
   //离开守卫:通过路由规则,离开该组件时被调用
   beforeRouteLeave (to, from, next) {
   }

6 路由懒加载

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')

7 v4.x

vue-router 3.x结合vue2使用

vue-router 4.x结合vue3使用

主要区别:创建路由模块的方式不同

import {createRouter,createWebHashHistory} from 'vue-router'
const router = createRouter({
  history: createWebHashHistory(),
  routes, 
  linkActiveClass:'router-link-active',//激活的 RouterLink 的默认类
})

// 创建并挂载根实例
const app = Vue.createApp({})
app.use(router)

路由跳转

    import { useRouter } from 'vue-router';
    setup(props, ctx) {
        const router = useRouter();
        const onClickLeft = () => {
            router.go(-1);
            ctx.emit('handleBack');
        };
        return {
            onClickLeft,
        };
    },

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值