当前位置: 首页 > news >正文

【vue(一))路由】

路由

  • 一、前端路由的理解
    • 1.SPA单页面应用
    • 2.路由
  • 二、路由实现本质
    • 1.浏览器的两种路由模式
      • (1)hash模式
      • (2)history模式
    • 2.避开浏览器默认行为
  • 三、几种跳转的对比
    • 1.location.href = '/url'
    • 2. history.pushState('/url')
    • 3.router.push('/url') -- Vue Router
    • 4.对比
  • 四、创建路由
    • 1.安装 Vue Router
    • 2.创建路由配置文件
    • 3.在main.js中注册路由
    • 4.在App.vue中显示路由组件
  • 五、`$route`和`$router` 的区别
  • 六、动态路由匹配
  • 七、嵌套路由,命名路由,路由重定向
  • 八、路由跳转的两种方式
  • 九、路由传递参数写法
    • 1.params参数
    • 2.query参数
    • 3.params和query传参的三种写法
    • 4.props传递
  • 十、路由元信息
  • 十一、路由导航守卫
    • 1.全局前置守卫
  • 十二、路由懒加载
    • 1.使用箭头函数+import动态加载
    • 2.使用箭头函数+require动态加载
    • 3.使用webpack的require.ensure技术

一、前端路由的理解

1.SPA单页面应用

(1)在前端技术早期,一个url对应一个页面。

eg:早期博客网站(传统的多页应用MPA

  • 点击首页的一篇文章
  • 浏览器向服务器发送请求
  • 服务器收到请求后,生成一个完整的HTML页面
  • 服务器把这个完整的HTML文件返回给浏览器
  • 浏览器完全刷新页面,丢掉原来的首页内容,加载新的HTML页面

(2)ajax出现,允许在不刷新页面的情况下发请求,随之出现SPA

  • 在SPA初期,在内容切换前后,页面的URL是一样的。
  • 问题一:SPA不会记住你的操作
    • 在博客网站点击帖子内容,但是URL并没有变,点击刷新,又回到首页,刚才的帖子页
  • 问题二:SEO 不够友好
    • 早期爬虫抓取网页内容,但是并不执行js,所以当它们访问SPA时,只能看到那个几乎是空白的HTML文件,而无法获取任何通过JavaScript动态加载的内容。

(3)因此路由出现了

路由的作用就是将浏览器的URL和用户看到的内容绑定起来。当用户浏览不同页面时,URL随之更新,但不需要从服务器重新加载。

2.路由

路由要解决的两个问题

  • (1)问题一
    • 浏览器默认行为:看到URL改变就会向服务器发请求。所以必须避开这种行为。
  • (2)问题二:
    • 感知URL变化,实现"前进/后退":让用户看到URL变化,但不刷新页面,同时记录历史

二、路由实现本质

1.浏览器的两种路由模式

模式描述特性
hash模式依赖 URL 的 哈希部分(# 后面的内容。当哈希值发生变化,触发hashchange事件。前端通过监听该事件,根据哈希值动态渲染页面内容。兼容所有现代浏览器哈希部分不会被发送到服务器url不美观无法利用浏览器的前进、后退功能进行复杂的路由操作
history模式基于 HTML5 History API功能强大需要服务器支持

(1)hash模式

hash模式的主要原理就是onhashchange()事件:

  • 页面hash值发生改变,无需向后端发起请求,window就可以监听事件的改变
window.onhashchange = function(event){console.log(event.oldURL, event.newURL);let hash = location.hash.slice(1);//location.hash返回当前 URL 中以 # 开头的 hash 部分//slice去掉#
}

(2)history模式

history 路由模式的实现,基于 HTML5 提供的 History 全局对象,它的方法有:

-在这里插入图片描述

  • history模式需要后台配置支持。如果后台没有正确配置,访问时会返回404
  • 如果想要切换到history模式,就要进行以下配置(后端也要进行配置)
const router = new VueRouter({mode: 'history',routes: [...]
})

2.避开浏览器默认行为

  • 不使用 <a href> 进行跳转,而是用 JS 控制
  • 用 history.pushState() 替代直接跳转 → 不触发请求
  • 监听页面的 popstate 事件 → 捕捉“前进/后退”

三、几种跳转的对比

1.location.href = ‘/url’

(1)刷新页面,破坏SPA体验
(2)等同于点击 <a href="/about">,是传统的多页跳转方式

2. history.pushState(‘/url’)

(1)无刷新页面
(2)浏览器提供的原生 API,属于 HTML5 History API 的一部分。
(3)只负责改变URL并更新浏览器的历史记录栈,不会自动处理视图更新

3.router.push(‘/url’) – Vue Router

(1)无刷新页面
(2)不仅可以改变 URL,还能够基于 URL 自动匹配并渲染相应的组件
(3)提供了诸如导航守卫、懒加载、参数解析等额外功能

4.对比

在这里插入图片描述

四、创建路由

1.安装 Vue Router

//vue2推荐@3.x
//vue3推荐@4.x
npm install vue-router@4

2.创建路由配置文件

  • 可以把路由规则放在routers.js文件,到时候在这引入就行
  • 路由插件
    • 1.全局注册RouterView 和 RouterLink 组件
    • 2.添加全局 $router 和 $route 属性
    • 3.启用 useRouter() 和 useRoute() 组合式函数
    • 4.触发路由器解析初始路由。
// src/router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';// 1. 安装 VueRouter 插件(关键!)
Vue.use(VueRouter);// 2. 引入需要路由控制的组件
import Home from '@/views/Home.vue';
import About from '@/views/About.vue';
import User from '@/views/User.vue';// 3. 定义路由规则
const routes = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',component: About},{path: '/user/:id', // 动态路由参数name: 'User',component: User,props: true // 将参数作为 props 传入组件},{path: '/login',redirect: '/auth' // 重定向},{path: '/auth',component: () => import('@/views/Auth.vue') // 懒加载(推荐)},{path: '*',component: () => import('@/views/NotFound.vue') // 404 页面}
];// 4. 创建路由实例
const router = new VueRouter({mode: 'history', // 可选:'hash' 或 'history'base: process.env.BASE_URL,routes  // 相当于 routes: routes
});// 5. 导出路由实例
export default router;

3.在main.js中注册路由

// src/main.js
import Vue from 'vue';
import App from './App.vue';// ✅ 引入路由
import router from '@/router';// ✅ 引入并使用 Vuex(可选)
import store from '@/store';new Vue({render: (h) => h(App),// ✅ 注册路由:让所有组件都能访问 $route 和 $routerrouter,// ✅ 注册 store(如果使用 Vuex)store}).$mount('#app');

4.在App.vue中显示路由组件

使用 <router-view> 显示组件内容
在这里插入图片描述

五、$route$router 的区别

注册完路由后,不管是路由组件还是非路由组件身上都有这两个属性

项目本质属性
$route当前路由的信息对象path,params,hash,query,fullPath,matched,name 等路由信息参数
$router路由实例对象路由的跳转方法,钩子函数

六、动态路由匹配

  • 在定义路由时,允许某些部分是动态变化的
  • 大多情况下,我们需要将给定匹配模式的路由映射到同一个组件,例如user组件的渲染会有用户id的不同
import User from './User.vue'// 这些都会传递给 `createRouter`
const routes = [// 动态字段以冒号开始,称之为路径参数{ path: '/users/:id', component: User },
]
  • 当一个路由被匹配时,它的 params 的值将在每个组件中以 route.params 的形式暴露出来
  • 通过更新 User 的模板来呈现当前的用户 ID
<template><div><!-- 当前路由可以通过 $route 在模板中访问 -->User {{ $route.params.id }}</div>
</template>

七、嵌套路由,命名路由,路由重定向

const routes = [// 重定向:根路径跳转到首页{ path: '/', redirect: { name: 'home' } },// 命名路由 + 嵌套路由{path: '/admin',name: 'admin',component: AdminLayout,children: [{path: 'user',name: 'admin-user',component: UserList,children: [{path: 'add',name: 'admin-user-add',component: UserAdd}]}]}
]
<!-- 使用命名路由跳转 -->
<router-link :to="{ name: 'admin-user-add' }">新增用户</router-link>

八、路由跳转的两种方式

  • 声明式导航 router-link
  • 编程式导航 push | replace
  • 声明式导航能做的,编程式导航都能做;但是编程式导航除了能进行路由跳转,还可以做其他业务逻辑。
    在这里插入图片描述

九、路由传递参数写法

1.params参数

  • 路径参数(是URL的一部分)
  • 在配置路由时需要占位
  • 给params后面加上代表参数可传可不传
  • 携带params参数时,使用to的对象写法只能用name配置!,不能用path配置

2.query参数

  • 不属于路径的一部分,
  • /home?k=v&k=v,配置路由的时候不需要占位

3.params和query传参的三种写法

使用router.push()
这里我感觉少用<router-link :to=''>传参吧,可以用它进行单纯的路由跳转?反正传参emmmm反正我有点绕。等用到了再说吧。

goSearch() {//搜索按钮的回调函数,需要向search路由跳转并传参给search//第一种传参方式:字符串// this.$router.push('/search/' + this.keyword + '?k=' + this.keyword.toUpperCase());//第二种传参方式:模板字符串// this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`);//第三种传参方式:对象写法this.$router.push({// path: '/search',  和params一起时不能用path只能namename: 'sousuo',params: { keyword: this.keyword },query: { k: this.keyword.toUpperCase() },})
}

4.props传递

props可以写成布尔值,对象模式,函数模式

    {name: 'search',  // 是当前路由的标识名称path: '/search/:keyword?',component: Search,// 将params参数和query参数映射成属性传入路由组件//写法一:布尔值,只能传递prams参数// props:true//写法二:对象写法-->死数据(额外给路由组件传递一些props)//props:{a:1,b:2}//写法三:函数 可以传params和query参数props: ($route)=> {return { keyword3: $route.params.keyword, keyword4: $route.query.keyword2 }},
//子组件接收
prop:[ 'keyword3','keyword4']

十、路由元信息

  • 你可能希望将任意信息附加到路由上,如过渡名称谁可以访问路由等
  • 这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到
  • 暂时没用到多少,后面用多了再说

一个例子:

//例如在home首页,我希望显示footer组件,但是在其他页面不想显示footer组件,我就可以写meta元信息{path: '/',component: () => import('@/pages/Home'),meta: {isHideFooter: true}},
    <!-- 利用路由元信息解决当前问题好处:一行代码就可以解决 --><Footer v-show="$route.meta.isHideFooter" />

十一、路由导航守卫

  • 全局前置/钩子:beforeEach、beforeResolve、afterEach
  • 路由独享的守卫:beforeEnter
  • 组件内的守卫:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
  • 暂时只用过全局前置守卫来进行页面跳转守卫

1.全局前置守卫

// GOOD
router.beforeEach((to, from, next) => {//to:获取到要跳转到的路由信息//from:获取到从哪个路由跳转过来来的信息// next();直接调用,代表直接放行next()
})

十二、路由懒加载

非懒加载

import List from '@/components/list.vue'
const router = new VueRouter({routes: [{ path: '/list', component: List }]
})

1.使用箭头函数+import动态加载

方案一(常用):

const List = () => import('@/components/list.vue')
const router = new VueRouter({routes: [{ path: '/list', component: List }]
})

2.使用箭头函数+require动态加载

const router = new Router({routes: [{path: '/list',component: resolve => require(['@/components/list'], resolve)}]
})

3.使用webpack的require.ensure技术

// r就是resolve
const List = r => require.ensure([], () => r(require('@/components/list')), 'list');
// 路由也是正常的写法  这种是官方推荐的写的 按模块划分懒加载 
const router = new Router({routes: [{path: '/list',component: List,name: 'list'}]
}))
http://www.dtcms.com/a/325399.html

相关文章:

  • uncalled4
  • 昆仑万维SkyReels-A3模型发布:照片开口说话,视频创作“一键改台词”
  • 使用行为树控制机器人(二) —— 黑板
  • 哈希、存储、连接:使用 ES|QL LOOKUP JOIN 的日志去重现代解决方案
  • Logistic Loss Function|逻辑回归代价函数
  • 实习学习记录
  • 集成电路学习:什么是URDF Parser统一机器人描述格式解析器
  • ttyd终端工具移植到OpenHarmony
  • 工业相机与智能相机的区别
  • 5G与云计算对代理IP行业的深远影响
  • 用 Python 绘制企业年度财务可视化报告 —— 从 Excel 到 9 种图表全覆盖
  • nvm安装详细教程(卸载旧的nodejs,安装nvm、node、npm、cnpm、yarn及环境变量配置)
  • 论文中PDF的公式如何提取-公式提取
  • Lightroom 安卓版 + Windows 版 + Mac 版全适配,编辑管理一站式,专业摄影后期教程
  • 【实用案例】录音分片上传的核心逻辑和实现案例【文章附有代码】
  • 智能双行框!百度全量上线AI搜索,是革新浪潮还是昙花一现?
  • 场外个股期权交易系统全球解决方案:监管协同与流动性创新——基于香港LEAP框架与多级清算体系的实践验证
  • 腾讯 iOA 测评 | 横向移动检测、病毒查杀、外设管控、部署性能
  • 智能合约执行引擎在Hyperchain中的作用
  • 飞算 JavaAI 智能进阶:从技术工具到金融科技开发范式的革新
  • 能力评估:如何系统评估你的技能和经验
  • “人工智能 +”新政即将出台,哪些领域将迎来发展风口?
  • 论文学习22:UNETR: Transformers for 3D Medical Image Segmentation
  • IDE认知革命:JetBrains AI Assistant插件深度调教手册(终极实战指南)
  • @ContextConfiguration
  • Java基础结课题-统计双色球中奖数
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘lightgbm’问题
  • yolo目标检测技术之yolo1到yolo5(二)
  • Profile.vue组件详细解析
  • 缓存的三大问题分析与解决