路由器的两种工作模式:
hash模式:(toB)
地址中永远带着#号,不美观,兼容性较好(#及其后面的内容就是hash值,hash值不会带给服务器);
若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
history模式:(toC)
兼容性较差;路径会提交给后台。
应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
hash :window.onhashchange监听路由改变。
- 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 testtitle>
- head>
- <body>
- <p>hash testp>
- <button id="btn1">修改 hashbutton>
-
- <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监听路由改变。
- 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 testtitle>
- head>
- <body>
- <p>history API testp>
- <button id="btn1">修改 urlbutton>
-
- <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>
v3.5.2
: 路由链接, 生成路由链接: 路由视图, 显示当前路由组件: 缓存路由组件对象
main.js
- import Vue from 'vue';
- import router from './router';//index.js可以简写
-
- new Vue({
- el: '#app',
- router,
- components: { App },
- template: '
' - });
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 to="/home" active-class="active">Go to Homerouter-link>
- <router-link :to="{name:'MyAbout',params:{id:1}}" replace>Go to Aboutrouter-link>
- p>
-
- <router-view>router-view>
- div>
- 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
- },
- ]
$route:路由参数对象:包含params/query/path/fullpath(query参数)/meta
$router:路由器对象:包含控制路由跳转的方法(push/replace/back)
作用:让路由组件更方便的收到参数。
- {
- 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
- }
- }
- }
"/about/68">Go to About -
- export const routes=[
- {
- path: '/',
- redirect: '/home',
- },
- {
- path: '/home',
- component: Home
- },
- {
- path: '/about/:mid',//使用占位符声明接收params参数
- component: About,
- props:true,//开启后,组件中可直接访问mid,需要声明接收
- },
- ]
-
- const {mid} = this.$route.params
-
-
- <router-link :to="/home/message/detail?id=666&title=你好">跳转router-link>
-
-
- <router-link
- :to="{
- path:'/home/message/detail',
- query:{
- id:666,
- title:'你好'
- }
- }"
- >跳转router-link>
-
-
-
- $route.query.id
this.$router.push(‘/home/’+id)//增加一条历史记录
this.$router.replace({name:'MyAbout',params:{id:1}})//替换当前历史记录
this.$router.go()
this.$router.back()
this.$router.forward()
导航守卫可以控制路由的访问权限。
全局前置守卫:初始化时执行、每次路由切换前执行(案例:登录后,才可以访问主页)
全局后置守卫:初始化时执行、每次路由切换后执行(修改网页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)表示不允许跳转
在路由配置上定义路由独享守卫
- const routes = [
- {
- path: '/users/:id',
- component: UserDetails,
- beforeEnter: (to, from) => {
- // reject the navigation
- return false
- },
- },
- ]
- //进入守卫:通过路由规则,进入该组件时被调用
- beforeRouteEnter (to, from, next) {
- },
- //离开守卫:通过路由规则,离开该组件时被调用
- beforeRouteLeave (to, from, next) {
- }
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
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,
- };
- },