-
2022-03-28 10:00:43
总结:
vue-router是vue项目的重要组成部分,用于构建单页应用。单页应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。路由的本质就是建立url和页面之间的映射关系
router 模式
hash / history
hash模式是vue-router的默认模式。hash指的是url锚点,当锚点发生变化的时候,浏览器只会修改访问历史记录,不会访问服务器重新获取页面。因此可以监听描点值的变化,根据描点值渲染指定dom。
hash监听方法:
window.addEventListener('hashchange', () => { const hash = window.location.hash.substr(1) // 根据hash值渲染不同的dom })
hash模式下,url可能为以下形式:
http://localhost:8080/index.html#/book?bookid=1history模式,url会如下面所示:
http://localhost:8080/book/1history模式
H5的history对象提供了pushState和replaceState两个方法,当调用这两个方法的时候,url会发生变化,浏览器访问历史也会发生变化,但是浏览器不会向后台发送请求。// 第一个参数:data对象,在监听变化的事件中能够获取到 // 第二个参数:title标题 // 第三个参数:跳转地址 history.pushState({}, "", '/a')
history监听方法:
通过监听popstate事件监听history变化,也就是点击浏览器的前进或者后退功能时触发。window.addEventListener("popstate", () => { const path = window.location.pathname // 根据path不同可渲染不同的dom })
once more
总体来讲就是 利用hash 或者history 模式修改部分 url,不会向后端发送请求,并且能监听到url变化,根据不同url 映射到不同页面Vue中实现原理
VueRouter核心是,通过Vue.use注册插件,在插件的install方法中获取用户配置的router对象。当浏览器地址发生变化的时候,根据router对象匹配相应路由,获取组件,并将组件渲染到视图上。1.url改变
2.触发事件监听
3.改变vue-router中的current变量
4.监视current变量的监视者
5.获取新的组件
6.render// 存储全局使用的Vue对象 let _Vue = null class VueRouter { // vue.use要求plugin具备一个install方法 static install (Vue) { // 判断插件是否已经安装过 if (VueRouter.install.installed) { return } VueRouter.install.installed = true _Vue = Vue // 将main文件中实例化Vue对象时传入的router对象添加到Vue的原型链上。 _Vue.mixin({ beforeCreate () { if (this.$options.router) { _Vue.prototype.$router = this.$options.router } } }) } constructor (options) { this.options = options // 用于快速查找route this.routeMap = {} this.data = _Vue.observable({ current: window.location.hash.substr(1) }) this.init() } init () { this.createRouteMap() this.initComponents(_Vue) this.initEvent() } createRouteMap () { // 遍历所有的路由规则 吧路由规则解析成键值对的形式存储到routeMap中 this.options.routes.forEach(route => { this.routeMap[route.path] = route.component }) } initComponents (Vue) { // 注册router-link组件 Vue.component('router-link', { props: { to: String }, methods: { clickHandler (e) { // 修改hash location.hash = this.to // 修改current,触发视图更新 this.$router.data.current = this.to e.preventDefault() } }, render (h) { return h('a', { attrs: { href: this.to }, on: { click: this.clickHandler } }, [this.$slots.default]) } }) const that = this // 注册router-view插件 Vue.component('router-view', { render (h) { const component = that.routeMap[that.data.current] return h(component) } }) } initEvent () { // 在hash发生更改的时候,修改current属性,触发组件更新 window.addEventListener('hashchange', () => { this.data.current = window.location.hash.substr(1) }) } } export default VueRouter
更多相关内容 -
VueRouter的实现原理——封装简易功能的VueRouter
2021-04-23 11:09:17VueRouter的实现原理Hash模式和History模式的区别表现形式的区别原理的区别History 模式的使用node 环境下支持 historyNginx 下支持 historyVueRouter 两种模式的实现原理Hash 模式History 模式实现思路VueRouter-...VueRouter的实现原理
Hash模式和History模式的区别
不管哪种模式,前端路由都是客户端路由的实现方式,也就是当路径发生变化时,不会向服务器发送请求,是利用js监视路径的变化。然后根据不同的地址渲染不同的内容,如果需要服务器内容,会发送Ajax请求来获取。
表现形式的区别
- hash 模式
https://music.163.com/#/discover/toplist
地址中会存在 # 号 - history 模式
https://music.163.com/discover/toplist
地址中没有# 类似于普通的地址,但是需要服务端配置支持
原理的区别
- hash 模式是基于锚点, 以及onhashchange 事件
- history 模式是基于 HTML5 中的 History API
- history.pushState() IE10 以后才支持
- history.replaceState() \
History 模式的使用
- History 需要服务器的支持
- 单页应用中,如果刷新页面,会向服务器发起请求,而服务器不存在这样的地址就会返回找不到该页面从而出现404
- 在服务端应该除了静态资源外都返回单页应用的 index.html
node 环境下支持 history
在 node 环境下,启用对history模式的支持可以通过 connect-history-api-fallback 这个中间件来完成
// 导入处理 history 模式的模块 const history = require('connect-history-api-fallback') // 导入 express const express = require('express') const app = express() // 注册处理 history 模式的中间件 app.use(history())
Nginx 下支持 history
- 从官网下载 nginx 的压缩包
- 把压缩包解压到 c 盘根目录,c:\nginx-1.18.0 文件夹
- 修改 conf\nginx.conf 文件
运行nginx服务器基本指令
启动
start nginx
重启
nginx -s reload
停止
nginx -s stop- 修改 conf\nginx.conf 文件
location / { root html; index index.html index.htm; #新添加内容 #尝试读取$uri(当前请求的路径),如果读取不到读取$uri/这个文件夹下的首页 #如果都获取不到返回根目录中的 index.html try_files $uri $uri/ /index.html; }
VueRouter 两种模式的实现原理
Hash 模式
- URL 中 # 后面的内容作为路径地址
- 监听 hashchange 事件
- 根据当前路由地址找到对应组件重新渲染
History 模式
- 通过 history.pushState() 方法改变地址栏
- 监听 popstate 事件
- 根据当前路由地址找到对应组件重新渲染
实现思路
从上图,可以大致了解一下 VueRouter 这个类中的结构:
上半部分是属性,下半部分是方法,其中+ 是实例方法,- 是静态方法。
install 是用来实现Vue.use 插件机制的方法。VueRouter-install 方法实现
要实现install方法,首先先分析一下该方法要做的事情:
- 判断当前插件是否已经被安装
- 把Vue构造函数记录到全局变量
- 把创建Vue实例时候传入的router对象注入到所有的Vue实例上
let _Vue; export default class VueRouter { static install(Vue) { // 1. 判断当前插件是否已经被安装 if(VueRouter.install.installed) return VueRouter.install.installed = true // 2. 把Vue构造函数记录到全局变量 _Vue = Vue // 3. 把创建Vue实例时候传入的router对象注入到所有的Vue实例上 // 利用混入让所有的vue实例加载router _Vue.mixin({ beforeCreate(){ // this.$options.name用来获取vue实例 data以外的属性 // new Vue( { router } ) if(this.$options.router) { _Vue.prototype.$router = this.$options.router } } }) } }
添加 VueRouter 的constructor
VueRouter 的构造函数要初始化三个属性,分别是: options、data、routeMap。
- options 是路由的构造配置对象
- data 应该是一个响应式的对象,其中有一个属性 current 用来记录当前我们的路由地址,这里我们该如何才能创建一个响应式的对象呢?可以使用Vue的observable方法
- routeMap 中记录了 options里的rules,rules解析出来 会以键值对的形式存在 routeMap中 ,key 就是路由地址,value 就是路由组件
constructor(options){ this.options = options this.data = _Vue.observable({ current:'/' }) this.routeMap = {} }
createRouterMap
接下来我们来实现VueRouter类中 createRouterMap 这个方法,它的作用就是把 options 中rules 路由规则解析出来以键值对的形式存储在routeMap上。
createRouterMap() { this.options.rules.forEach(route => this.routeMap[route.path] = route.component) }
initComponents
下一步,来创建initComponents 方法,这个方法里我们要创建两个组件。分别是:RouterLink 和 RouterView
创建RouterLink 组件
let _Vue; export default class VueRouter { static install(Vue) { // 1. 判断当前插件是否已经被安装 if (VueRouter.install.installed) return VueRouter.install.installed = true // 2. 把Vue构造函数记录到全局变量 _Vue = Vue // 3. 把创建Vue实例时候传入的router对象注入到所有的Vue实例上 // 利用混入让所有的vue实例加载router _Vue.mixin({ beforeCreate() { // this.$options.name用来获取vue实例 data以外的属性 // new Vue( { router } ) if (this.$options.router) { _Vue.prototype.$router = this.$options.router this.$options.router.init() } } }) } constructor(options) { this.options = options this.routeMap = {} this.data = _Vue.observable({ current: '/' }) } createRouterMap() { this.options.routes.forEach(route => this.routeMap[route.path] = route.component) } initComponents(Vue) { // 创建RouterLink组件 Vue.component('router-link', { props: { 'to': { type: String } }, template: `<a :href="to"><slot></slot></a>` }) } init() { this.createRouterMap() this.initComponents(_Vue) } }
用自己的VueRouter 替换掉官方的运行后,发现报错
报错的意思是,运行时版本的Vue 不支持 tempalte 模板,需要打包的时候提前编译。
如果要让我们的template被支持可以使用完整版的Vue,完整包包含运行时和编译器,体积比运行时版本大10k左右,程序运行的时候把模板转换成render函数
@vue/cli 自动安装的就是 运行时版本报错的解决
第一种方案——引入完整版Vue,可以在vue.config.js中 加入配置
module.exports = { runtimeCompiler: true }
第二种方案——使用render函数替换掉tempalte
render(h) { return h('a', { attrs: { href: this.to } }, [this.$slots.default]) } // template: `<a :href="to"><slot></slot></a>`
创建RouterView组件
// 记录一下this let self = this Vue.component('router-view',{ render(h){ // routeMap以key value形式记录了path和component // data.current 记录了当前页面的path return h(self.routeMap[self.data.current]) } })
在routerlink中添加点击事件,修改地址
为了能够让链接成功完成跳转展示组件,我们需要对routerlink中的a标签添加点击事件
并且要在点击的时候,把最新的path更新到router实例的current上.
我们借助于history的pushState方法 该方法会修改浏览器地址栏中的地址,但不会向服务器发起请求,并且还可以将新地址记录在历史中
Vue.component('router-link', { props: { 'to': { type: String } }, render(h) { return h('a', { attrs: { href: this.to }, on: { click: this.clickHandle } }, [this.$slots.default]) }, methods: { clickHandle(e) { history.pushState({}, "", this.to) // 把点击的链接地址 更新到 current 上 this.$router.data.current = this.to e.preventDefault() } } // template: `<a :href="to"><slot></slot></a>` })
initEvent
现在功能基本上已经差不多了,但是还存在一个小问题,就是当我们点击浏览器的前进或者后退按钮的时候,组件不能实现切换展示,主要思路就是通过添加popstate监听地址变化,下面我们来完善该功能
initEvent(){ // window.addEventListener("popstate",()=>{ this.data.current = window.location.pathname }) }
完整代码
let _Vue; export default class VueRouter { static install(Vue) { // 1. 判断当前插件是否已经被安装 if (VueRouter.install.installed) return VueRouter.install.installed = true // 2. 把Vue构造函数记录到全局变量 _Vue = Vue // 3. 把创建Vue实例时候传入的router对象注入到所有的Vue实例上 // 利用混入让所有的vue实例加载router _Vue.mixin({ beforeCreate() { // this.$options.name用来获取vue实例 data以外的属性 // new Vue( { router } ) if (this.$options.router) { _Vue.prototype.$router = this.$options.router console.log(this.$options.router.init); this.$options.router.init() } } }) } constructor(options) { this.options = options this.routeMap = {} this.data = _Vue.observable({ current: '/' }) } createRouterMap() { this.options.routes.forEach(route => this.routeMap[route.path] = route.component) } initComponents(Vue) { // 创建RouterLink组件 Vue.component('router-link', { props: { 'to': { type: String } }, render(h) { return h('a', { attrs: { href: this.to }, on: { click: this.clickHandle } }, [this.$slots.default]) }, methods: { clickHandle(e) { history.pushState({}, "", this.to) // 把点击的链接地址 更新到 current 上 this.$router.data.current = this.to e.preventDefault() } } // template: `<a :href="to"><slot></slot></a>` }) let self = this Vue.component('router-view', { render(h) { // routeMap以key value形式记录了path和component // data.current 记录了当前页面的path return h(self.routeMap[self.data.current]) } }) } init() { this.createRouterMap() this.initComponents(_Vue) this.initEvent() } initEvent() { // window.addEventListener("popstate", () => { this.data.current = window.location.pathname }) } }
- hash 模式
-
Vue Router4路由
2021-08-04 15:12:48Vue Router4路由 官网:https://next.router.vuejs.org/zh/guide/essentials/route-matching-syntax.html 1、在vue-router是什么? Vue.js 的官方路由(就这么简单一句话) 2、Vue Router4 新特性 简单对比总结了...Vue Router4路由
目录
官网:vue-router4
1、Vue-router是什么?
Vue.js 的官方路由(就这么简单一句话)
2、Vue Router4 新特性
简单对比总结了一下
- Vue3支持最新版本由于Vue 3 引入了
createApp
API,该API更改了将插件添加到Vue实例的方式。 因此,以前版本的Vue Router将与Vue3不兼容。Vue Router 4 引入了createRouter
API,该API创建了一个可以在Vue3中安装 router 实例。 - History选项在Vue Router 4中,这些模式已被抽象到模块中,可以将其导入并分配给新的
history
选项。 这种额外的灵活性让我们可以根据需要自定义路由器。
// Vue Router 4 import { createRouter, createWebHistory } from "vue-router"; export default createRouter({ history: createWebHistory(), routes: [], });
- 动态路由Vue Router 4 提供了
addRoute
方法实现动态路由。这个方法平时比较少用到,但是确实有一些有趣的用例。 例如,假设我们要为文件系统应用程序创建UI,并且要动态添加路径。 我们可以按照以下方式进行操作:
methods: { uploadComplete (id) { router.addRoute({ path: `/uploads/${id}`, name: `upload-${id}`, component: FileInfo }); } }
-
导航守卫可以返回值并非next导航守卫是Vue Router的钩子,允许用户在跳转之前或之后运行自定义逻辑,例如
beforeEach
,beforeRouterEnter
等。它们通常用于检查用户是否有权访问某个页面,验证动态路由参数或销毁侦听器。在版本4中,我们可以从hook 方法中中返回值或Promise。 这样可以方便快捷地进行如下操作:// Vue Router 3 router.beforeEach((to, from, next) => { if (!isAuthenticated) { next(false); } else { next(); } }) // Vue Router 4 router.beforeEach(() => isAuthenticated);
3、安装和配置router.js文件
npm install vue-router@4//一般使用npm,4.x的版本最新
import { createRouter, createWebHashHistory } from 'vue-router' import Server from "../components/distribution_services/Index.vue" import Data from "../components/data_processing/Index.vue" import Visual from "../components/three_dimensional_visualization/Index.vue" import Details from "../components/authorization_details/index.vue" import Buy from "../components/authorized_purchase/Index.vue" import Terrain from "../components/distribution_services/terrain/Index.vue" import Image from "../components/distribution_services/image/Index.vue" import Lodmodel from "../components/distribution_services/lodModel/Index.vue" import Resource from "../components/distribution_services/assets/Index.vue" import Scene from "../components/distribution_services/scene/Index.vue" import Tile from "../components/distribution_services/model/Index.vue" import Tilt from "../components/distribution_services/osgb/Index.vue" const router = createRouter({ history: createWebHashHistory(), // hash模式:createWebHashHistory,history模式:createWebHistory //hash 模式使用URL哈希来模拟完整的URL,以便在URL更改时不会重新加载页面。 history 模式利用 HTML5 History API 来实现URL导航,也是无需重新加载页面。 linkExactActiveClass: 'active',//配置高亮 routes: [{ path: '/', name: 'data', components: { out: Data } }, { path: '/server', name: 'server', redirect: '/server/terrain', //首个重定向 components: { out: Server }, //路由嵌套使用children children: [{ path: 'terrain', name: 'terrain', components: { inside: Terrain }, }, { path: 'image', name: 'image', components: { inside: Image }, }, { path: 'lodmodel', name: 'lodmodel', components: { inside: Lodmodel }, }, { path: 'resource', name: 'resource', components: { inside: Resource }, }, { path: 'scene', name: 'scene', components: { inside: Scene }, }, { path: 'tile', name: 'tile', components: { inside: Tile }, }, { path: 'tilt', name: 'tilt', components: { inside: Tilt }, }, ] }, { path: '/visual', name: 'visual', components: { out: Visual } }, { path: '/details', name: 'details', components: { out: Details } }, { path: '/buy', name: 'buy', components: { out: Buy } } ] }) export default router
以上是routerjs文件,在vue4中引入router
app.use(router)
高亮配置
- 通过router.js中 linkExactActiveClass: ‘active’,//配置高亮
- 然后在css中.router-link-active{background:#fff}即可
4、router-link和router-view
router-link
自定义组件,用来创建链接,可实现不重新加载页面的情况下更改URL地址,通过传入to 属性指定链接。router-view
将显示与 url 对应的组件,相当于一个视图窗口
视图注意点:我们如果多个router-view的时候,怎么指定view视图窗口?
配置router.js文件中components中可以看到,属性名称是router-view的对应名称,自定义即可5、路由嵌套
如你所见,
children
配置只是另一个路由数组,就像routes
本身一样。因此,你可以根据自己的需要,不断地嵌套视图。6、编程式导航
这个更编程化思想一点,我个人用到link连接多一点
6.1导航不同位置
除了使用
<router-link>
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。在 Vue 实例中,你可以通过
$router
访问路由实例。因此你可以调用this.$router.push
。想要导航到不同的 URL,可以使用
router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。声明式 编程式 <router-link :to="...">
router.push(...)
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
// 字符串路径 router.push('/users/eduardo') // 带有路径的对象 router.push({ path: '/users/eduardo' }) // 命名的路由,并加上参数,让路由建立 url router.push({ name: 'user', params: { username: 'eduardo' } }) // 带查询参数,结果是 /register?plan=private router.push({ path: '/register', query: { plan: 'private' } }) // 带 hash,结果是 /about#team router.push({ path: '/about', hash: '#team' })
注意:如果提供了
path
,params
会被忽略,上述例子中的query
并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的name
或手写完整的带有参数的path
:const username = 'eduardo' // 我们可以手动建立 url,但我们必须自己处理编码 router.push(`/user/${username}`) // -> /user/eduardo // 同样 router.push({ path: `/user/${username}` }) // -> /user/eduardo // 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益 router.push({ name: 'user', params: { username } }) // -> /user/eduardo // `params` 不能与 `path` 一起使用 router.push({ path: '/user', params: { username } }) // -> /user
由于属性
to
与router.push
接受的对象种类相同,所以两者的规则完全相同。6.2替换当前位置
它的作用类似于
router.push
,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。声明式 编程式 <router-link :to="..." replace>
router.replace(...)
也可以直接在传递给
router.push
的routeLocation
中增加一个属性replace: true
:router.push({ path: '/home', replace: true }) // 相当于 router.replace({ path: '/home' })
6.3横跨历史
该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于
window.history.go(n)
。图下所示// 向前移动一条记录,与 router.forward() 相同 router.go(1) // 返回一条记录,与router.back() 相同 router.go(-1) // 前进 3 条记录 router.go(3) // 如果没有那么多记录,静默失败 router.go(-100) router.go(100)
6.4篡改历史
router.push
、router.replace
和router.go
是window.history.pushState
、window.history.replaceState
和window.history.go
的翻版,它们确实模仿了window.history
的 API。
因此,在使用 Vue Router 时,操作历史记录就会觉得很熟悉。7、重定向
7.1重定向得使用场景
首先学习和使用一项技术要知道为什么要用?应用场景是什么?在官网中并没有直接解释说明,只是上来告诉如何去用
下边看例子
以上两图得区别是什么?当我点击一级路由时会显示二级目录,但是这个时候我想默认选中/重定向一个二级路由,这时候怎么办?当我点击一级路由时候,这个时候重定向二级路由中一个,当成默认选项
7.2如何设置重定向?
- 重定向也是通过
routes
配置来完成,下面例子是从/a
重定向到/b
:
const routes = [{ path: '/home', redirect: '/' }]
- 重定向的目标也可以是一个命名的路由:
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
- 甚至是一个方法,动态返回重定向目标:
const routes = [ { // /search/screens -> /search?q=screens path: '/search/:searchText', redirect: to => { // 方法接收目标路由作为参数 // return 重定向的字符串路径/路径对象 return { path: '/search', query: { q: to.params.searchText } } }, }, { path: '/search', // ... }, ]
8、导航守卫
导航守卫,顾名思义就是用户在跳转之前或之后运行自定义逻辑来实现一定的目的.
应用场景当没有登录的时候导航跳转的时候,重定向到login路由中(登录和内容区域是同一个页面)
// to代表将要访问的路径 // from代表从哪个路径跳转过来 // next是函数,表示放行 router.beforeEach((to,from,next) => { if(to.path === '/login') return next(); const tokenStr = window.sessionStorage.getItem('token');//获取token值 if(!tokenStr) return next('/login'); next() })
- Vue3支持最新版本由于Vue 3 引入了
-
Vue中路由 (Vue Router)
2021-12-23 15:13:38用来在vue中实现组件之间的动态切换Vue中路由 (Vue Router)
一、 vue中路由 Router
路由:根据请求的路径按照一定的路由规则进行请求的转发从而帮助我们实现统一请求的管理
概念:它和vue.js的核心深度集成,让构成单页面应用变得易如反掌
理解:让组件使用变得更加灵活,路由可以根据用户访问的url不同动态切换当前使用的组件
1、作用
用来在vue中实现组件之间的动态切换
- 路由核心功能:根据用户访问的url动态切换组件
- 路由是配合组件一起使用的
- 路由使用步骤
1. 创建组件 2.创建路由( 1.管理组件 2.制定路由规则) 3.将路由交由vue管理 在vue中注册路由 4.在vue实例范围内指定位置,使用路由选中组件
2、使用路由
(1)引入路由
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> //vue 路由js
(2)创建组件对象
//声明组件模板 const login = { template:'<h1>登录</h1>' }; const register = { template:'<h1>注册</h1>' };
(3)定义路由对象的规则
//创建路由对象 const router = new VueRouter({ routes:[ {path:'/login',component:login}, //path: 路由的路径 component:路径对应的组件 {path:'/register',component:register} ] });
(4)将路由对象注册到vue实例
const app = new Vue({ el: "#app", data: { username:"小陈", }, methods: {}, router:router //设置路由对象 });
(5)在页面中显示路由的组件
<!--显示路由的组件--> <router-view></router-view>
(6)根据连接切换路由
<a href="#/login">点我登录</a> <a href="#/register">点我注册</a>
3、vue中路由 Router案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>route的基本使用</title> </head> <body> <div id="app"> {{msg}} <!--4、路由选中的组件展示--> <div><router-view></router-view></div> </div> </body> </html> <script src="../js/vue-min.js"></script> <script src="../js/vue-router.js"></script> <script> const login={ template:`<div><h2>登录组件</h2></div>` } const reg={ template:`<div><h2>注册组件</h2></div>` } //创建路由 1、管理组件 2、配置路由规则 const router=new VueRouter({ // 指定路由规则 routes:[ {path:"/login",component:login}, {path:"/register",component:reg} ] }); new Vue({ el:"#app", data:{ msg:"route的基本使用" }, // 3.将路由对象注册给vue实例 router }) </script>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CKpPylBL-1640243602421)(image/image.png)]
二、通过超链接切换路由的方式
1、链接切换路由
<!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a>
- 案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>route的基本使用</title> </head> <body> <div id="app"> {{msg}} <!--4、路由选中的组件展示--> <div><router-view></router-view></div> <!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a> </div> </body> </html> <script src="../js/vue-min.js"></script> <script src="../js/vue-router.js"></script> <script> const login={ template:`<div><h2>登录组件</h2></div>` } const reg={ template:`<div><h2>注册组件</h2></div>` } //路由错误时的提示组件 const notFound={ template:`<div><h2>你访问的路径有误,请重新输入</h2></div>` } //创建路由 1、管理组件 2、配置路由规则 const router=new VueRouter({ // 指定路由规则 routes:[ {path:"/",redirect:"/login"},//配置根路由 切换方式为:重定向到指定路径 {path:"/login",component:login}, {path:"/register",component:reg}, {path:"*",component:notFound} //路径错误时的提示 ] }); new Vue({ el:"#app", data:{ msg:"route的基本使用" }, // 3.将路由对象注册给vue实例 router }) </script>
2、router-link使用
作用:用来替换我们在切换路由时使用a标签切换路由
好处:就是可以自动给路由路径加入#不需要手动加入
(1)使用router-link切换路由
<router-view></router-view> <!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a> <!--使用router-link切换路由--> <hr/> <router-link to="/login">登录组件</router-link> <router-link to="/register">注册组件</router-link>
(2)根据路径去切换路由
<router-view></router-view> <!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a> <!--使用router-link切换路由--> <hr/> <router-link to="/login">登录组件</router-link> <router-link to="/register">注册组件</router-link> <hr/> <!--根据路径去切换路由 --> <router-link :to="{path:'/login'}">登录组件</router-link> <router-link :to="{path:'/register'}">注册组件</router-link>
(3)根据名称去切换路由 官方推荐 解耦合
官方建议使用名称切换,可以和当前路由配置的path解耦合 修改path属性不会影响到路由切换
<router-view></router-view> <!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a> <!--使用router-link切换路由--> <hr/> <router-link to="/login">登录组件</router-link> <router-link to="/register">注册组件</router-link> <hr/> <!--根据路径去切换路由--> <router-link :to="{path:'/login'}">登录组件</router-link> <router-link :to="{path:'/register'}">注册组件</router-link> <hr/> <!--根据名称去切换路由 官方推荐--> <hr/> <router-link :to="{name:'login'}">登录组件</router-link> <router-link :to="{name:'register'}">注册组件</router-link>
# 总结: 1.router-link 用来替换使用a标签实现路由切换 好处是不需要书写#号直接书写路由路径 2.router-link to属性用来书写路由路径 tag属性:用来将router-link渲染成指定的标签
三、通过js切换路由的方式
当前vue实例中 存在两个路由相关的对象
$router 当前路由对象 | $router路由管理器对象
切换路由使用时 路由管理器对象
$router
- 语法:
this.$router.push({name:"目标路由的name属性值"})
2、通过js切换路由的方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>路由的切换</title> </head> <body> <div id="app"> <router-view></router-view> <!--根据名称去切换路由 官方推荐--> <hr/> <router-link :to="{name:'login'}">登录组件</router-link> <router-link :to="{name:'register'}">注册组件</router-link> <hr/> <button @click="toLogin()">切换到登录</button> </div> </body> </html> <script src="../js/vue-min.js"></script> <script src="../js/vue-router.js"></script> <script> const login = { template: `<div><h2>登录组件</h2></div>` } const reg = { template: `<div><h2>注册组件</h2></div>` } //路由错误时的提示组件 const notFound = { template: `<div><h2>你访问的路径有误,请重新输入</h2></div>` } //2、创建路由 1、管理组件 2、配置路由规则 const router = new VueRouter({ // 指定路由规则 routes: [ {path: "/", redirect: "/login"},//配置根路由 切换方式为:重定向到指定路径 {path: "/login", component: login, name: "login"}, {path: "/register", component: reg, name: "register"}, {path: "*", component: notFound} //路径错误时的提示 ] }); new Vue({ el: "#app", data: { msg: "route的基本使用" }, methods: { toLogin() { // 发送请求 // axios.get("url").then(()=>{}) // 正确响应时切换到登录页面 当前路由 routrt VueRouter路由管理对象 console.log(this); //使用路由管理器对象 推入新的路由对象 替换原有的路由 this.$router.push({name:"login"}); } }, // 3.将路由对象注册给vue实例 router: router }) </script>
2、切换到同一路由报错
-
通过js程序切换路由时 存在的一个错误提示
-
原因:反复切换同一路由组件出现错误提示:
vue-router.js:2071 Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/login".
-
解决方案:
(1)通过程序去切换路由时,添加一个判断,如果要切换的是对应的路由,使用的路由组件不切换
methods: { toLogin() { console.log(this); //使用路由管理器对象 推入新的路由对象 替换原有的路由 if(this.$route.name!="login"){ //判断 当前的路由对象是否要切换的路由 this.$router.push({name:"login"}); } }, toRegister() { //使用路由管理器对象 推入新的路由对象 替换原有的路由 if(this.$route.name!="register") this.$router.push({name:"register"}); } }
(2)通过配置的形式
- 反复切换同一个路由出现问题的解决方案 (配置信息)
const VueRouterPush = VueRouter.prototype.push VueRouter.prototype.push = function push (to) { return VueRouterPush.call(this, to).catch(err => err) }
四、默认路由
作用:用来在第一次进入界面是显示一个默认的组件
//2、创建路由 1、管理组件 2、配置路由规则 const router = new VueRouter({ // 指定路由规则 routes: [ {path: "/", redirect: "/login"},//配置根路由 切换方式为:重定向到指定路径 {path: "/login", component: login,name:"login"}, {path: "/register", component: reg,name:"register"}, {path: "*", component: notFound} //路径错误时的提示 ] });
五、路由中参数传递
1、第一种方式传递参数 传统方式
(1)通过?号形式拼接参数
<router-link to="/login?id=21&name=zhangsan">我要登录</router-link>
(2)组件中获取参数
const login = { template:'<h1>用户登录</h1>', data(){return {}}, methods:{}, created(){ console.log("=============>"+this.$route.query.id+"======>"+this.$route.query.name); } };
2、第二种方式传递参数 restful风格
指定动词:
get post put delete
(1)通过使用路径方式传递参数
<router-link to="/register/24/张三">我要注册</router-link> var router = new VueRouter({ routes:[ {path:'/register/:id/:name',component:register} //定义路径中获取对应参数 ] });
(2)组件中获取参数
const register = { template:'<h1>用户注册{{ $route.params.name }}</h1>', created(){ console.log("注册组件中id: "+this.$route.params.id+this.$route.params.name); } };
六、 嵌套路由
1、声明最外层和内层路由
<template id="product"> <div> <h1>商品管理</h1> <router-link to="/product/add">商品添加</router-link> <router-link to="/product/edit">商品编辑</router-link> <router-view></router-view> </div> </template> //声明组件模板 const product={ template:'#product' }; const add = { template:'<h4>商品添加</h4>' }; const edit = { template:'<h4>商品编辑</h4>' };
2、创建路由对象含有嵌套路由
const router = new VueRouter({ routes:[ { path:'/product', component:product, children:[ {path:'add',component: add}, {path:'edit',component: edit}, ] }, ] });
3、注册路由对象
const app = new Vue({ el: "#app", data: {}, methods: {}, router,//定义路由对象 });
4、测试路由
<router-link to="/product">商品管理</router-link> <router-view></router-view>
七、综合案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>router</title> </head> <body> <div id="app"> {{msg}} <a href="#/users">点击切换展示所有</a> <router-link to="/users">点击切换展示所有</router-link> <router-link :to="{path:'/users'}">点击切换展示所有</router-link> <router-link :to="{name:'Users'}">点击切换展示所有</router-link> <hr/> <a href="#/users/userAdd">添加</a> <!--4、在vue实例范围内使用路由选中组件--> <router-view/> </div> </body> </html> <!--展示所有用户组件模板template--> <template id="users"> <div> <table border="1"> <tr> <td>编号</td> <td>名称</td> <td>年龄</td> <td>薪资</td> <td>操作</td> </tr> <tr v-for="(user,index) in users" :key="user.id"> <td>{{user.id}}</td> <td>{{user.name}}</td> <td v-text="user.age"></td> <td v-html="user.salary"></td> <td><a href="">删除</a> | <router-link :to="{name:'UserUpdate',query:{id:user.id}}">修改</router-link></td> </tr> </table> <!--展示子路由选中的组件--> <router-view/> </div> </template> <script src="../js/vue-min.js"></script> <script src="../js/vue-router.js"></script> <script> //1、创建组件 //展示所有用户组件 const users = { template:"#users", data(){ return{ users:[] } }, created(){ //发送异步请求 接收数据交给当前组件管理 /* axios.get("url").then(response=>{ this.users = response.data }).catch(erro=>{ })*/ this.users = [{id:1 , name:"王恒杰",age:18,salary:18},{id:2 , name:"杨福君",age:58,salary:58}] } } const userAdd = { template:`<div>名称:<input type="text" v-model="user.name"/> <br/> 年龄:<input type="text" v-model="user.age"/><br/> 薪资:<input type="text" v-model="user.salary"/><br/> <button @click="addUser">添加</button></div>` , data(){ return{ user:{} } }, methods:{ addUser(){ //发送异步请求 完成数据添加 用户数据接收 /*axios.post("url", this.user).then(response=>{ }).catch(error=>{ })*/ //2 切换路由 this $route 当前路由对象 Object | $router 当前路由管理器对象 VueRouter this.$router.push({name:"Users"}) } } } const userUpdate = { template:`<div>编号:<input type="text" v-model="user.id"/> <br/>名称:<input type="text" v-model="user.name"/> <br/> 年龄:<input type="text" v-model="user.age"/><br/> 薪资:<input type="text" v-model="user.salary"/><br/><button @click="updateUser">修改</button></div>` , data(){ return{ user:{} } }, methods:{ updateUser(){ //切换路由 切换到展示所有路由 this.$router.push({name:"Users"}) } }, created(){ let id = this.$route.query.id; //发送异步请求查询数据 数据回显 /*axios.get("url?id="+id).then(response=>{ this.user= response.data }).catch(error=>{})*/ this.user = {id,name:"liuh",age:18,salary:18} } } //2、创建路由 a、管理组件 b、配置路由规则 [/users - 组件] const router = new VueRouter({ routes:[ {path:"/users" , component:users , name:"Users" , /*配置路由的子路由 注意: path属性中不能以/开头 切换子路由:/users/userAdd */ children:[ {path:"userAdd" , component:userAdd , name:"UserAdd"}, {path:"userUpdate" , component:userUpdate , name:"UserUpdate"} ] } , /*{path:"/userAdd" , component:userAdd , name:"UserAdd"}*/ ] }); new Vue({ el:"#app" , data:{ msg:"路由嵌套!" }, //3、将路由交由vue实例管理 router }) </script>
-
Vue-Router2.X多种路由实现方式总结
2021-01-21 11:58:19注意:vue-router 2只适用于Vue2.x版本,...import VueRouter from 'vue-router' import App from './App.vue' Vue.use(VueRouter) 1.定义组件,这里使用从其他文件import进来 import index from './components/inde -
Vue Router 4 的使用,一篇文章给你讲透彻
2022-02-06 19:12:17Vue 3.X 使用Vue Router 4.x 进行路由配置,本文我们就来研究下如何使用Vue Router 4.x,本文中所有的使用方式都是使用 Composition API的方式。 本文通过一步步介绍Vue Router 4.x的使用,来搭建一个简单的博客系统... -
VueRouter之构建VueRouter对象以及new Vue涉及的处理
2018-07-19 16:30:39前言 当程序加载执行完vue-router文件,就执行new VueRouter()...在第一篇文章中的实例中,调用new VueRouter()来创建router对象,VueRouter()具体的处理逻辑如下: 从上面的处理逻辑中可以看出,new VueRout... -
vue router添加自定义参数
2022-04-09 18:03:42通常需要在router里面添加参数用于特定的场景,但是官方提供的API只给出几个参数 在meta里面自定义添加参数即可 动态参数需要在动态路由里添加 取值从meta中取值即可 -
Vue router2.0
2022-04-24 15:58:03使用Vue安装 npm install vue-router --save 路由的引入 import router from './router' /* eslint-disable no-new */ new Vue({ el: '#app', store, router, components: { App }, template: '<App/>... -
VueRouter-router 与 route 区别
2021-09-17 17:02:31router 是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数的到的一个router对象。这个对象是一个全局对象,他包含可所有路由包含许多关键性的对象和属性 2.route route是一个跳转路由对象,每... -
VueRouter — vue路由hash模式和history模式
2022-03-23 15:32:19目录一、前言二、hash模式三、history模式 一、前言 ...const router = new VueRouter({ routes, mode: "history" }) history模式: 二、hash模式 最开始学习超链接a时,就可以利用锚点”#”实现跳转 -
Vue Router 参数接收
2021-11-15 15:37:10query 方式 请求头中是...title=电影这种带有?的形式。 :to=" ":表示to属性里边是表达式 query:属性用作传参 <router-link :to="{ name:'content', // query :{ id: n.id, title: n.title . -
vue-router源码浅显分析(一)--Vue.use(VueRouter), new VueRouter(options),HashHistory
2019-02-21 09:42:001,vue中使用vueRouter需要通过vue.use(vueRouter),众所周知,这里实际上调用了VueRouter的install方法,对Vue进行了扩展,vueRouter的install方法如下: function install (Vue) { //如果已经挂载了,跳过 if ... -
Vue | Vue Router 路由的使用
2021-01-21 17:02:04首先,创建一个 vue-cli 项目,可参考链接: ...import VueRouter from 'vue-router' Vue 中需要显示声明才能使用: Vue.use(VueRouter); 1、在 src 的 components 目录下,新建三个 Component:Main.v -
Vue Router系列之 base 配置项解释
2022-02-21 14:48:10目录1、示例后记 Vue Router 版本号为 v3.x ...const router = new VueRouter({ // 配置单页应用的基本路径 base: '/app/', // history模式,访问不带# mode: 'history', routes }) 效果如下: 页面中访问 -
Vue Router详细教程
2020-07-31 10:07:00Vue.use(VueRouter) //2 定义路由 const routes = [ ] //3 创建router实例 const router = new VueRouter({ routes }) //4 导出router实例 export default router 2.挂载到vue实例中 在main.js中引入router import ... -
Vue router 正则表达式限制路由传参
2021-07-15 13:04:42Vue router 里 path: “/redirect/:path(.*)” 是什么意思? 认真看了下, 有 “path:” 和 “/:” 应该是动态路由 可 (.*) 是什么东西? 哎呀, 这个我不知道呀! 被梅子发现我这么无知, 面子都不要了, 此时此刻必须冷静... -
Vue Router的介绍、安装及入门
2022-03-06 22:48:48Vue Router 是Vue.js的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括: 嵌套路由映射 动态路由选择 模块化、基于组件的路由配置 路由参数、查询、通配符 展示由 Vue.js... -
vuerouter 4.0 + vue3 + vuex 实现动态路由
2021-12-07 17:02:19之前自学过vue-router,但都是停留在静态路由的层面,对于动态路由的实现一窍不通,刚好公司让维护一个使用了动态路由的项目,所以参照项目和网上的信息自己实现了一下,做个记录。 使用vuecli4.5创建的小项目,... -
无法import VueRouter from ‘vue-router’
2020-10-16 23:20:46cnpm install -g vue-router 安装vue-router成功之后,却无法导入包 在项目目录下查看package.json,发现没有vue-router这个依赖 查阅资料,需使用命令 cnpm install -g --save-dev vue-router 成功安装并... -
vue router 动态路由清除
2021-09-07 16:13:34重置matcher可达到路由...import Router from 'vue-router' import { constantRouterMap } from '...' //导入初始化router // 传入当前router export function resetRouter (router) { const createRouter = () => -
vue项目——Vue Router路由的使用
2020-12-20 19:06:34前言:学习vue也有一段时间了,这里把学习整个vue项目中...一、Vue RouterVue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。我简单理解就是我们在有的页面中看到... -
学习 Vue router v3.x和4.x的一个区别
2022-04-02 10:06:28vue-router v3.x和4.x的一个区别 动态路由匹配3.x的时候使用 { path: '*',component: 404page } 匹配所有路由,返回404页面。 4.x { path:'/:pathMatch(.*)*',component: 404page } 使用以前的*语法会报错,... -
vue-router4路由报“[Vue Router warn] No match found for location with path
2022-03-09 09:02:08这里出现该问题的原因: 在路由配置了参数路径 但是,跳转的路径没有参数: 因此控制台出现了: -
Vue router 3.x 实现路由规则增删
2021-01-15 17:16:37vue 项目的权限限制功能, 有一种实现方案是这样的 进入项目 只设置没有权限要求的路由 向后台提供当前用户的权限 后台根据用户权限, 返回该用户可以用的路由信息 将路由信息翻译成 “符合 routes 选项要求的数组” ... -
Vue Router 路由(路由守卫)---route
2020-07-11 22:28:551、是什么 简单来说,导航守卫就是路由跳转前、中、后过程中的一些钩子函数,这个函数能让你操作一些其他的事儿,这就是导航守卫。...const router = new VueRouter({ ... }) router.beforeEach((to, from, next -
Vue源码 Vue Router(一)路由注册
2021-06-19 16:36:35Vue源码 Vue Router(一)路由注册Vue源码 Vue Router(一)路由注册Vue-Router路由注册`Vue.use`路由安装总结Vue源码学习目录 Vue源码 Vue Router(一)路由注册 学习内容和文章内容来自 黄轶老师 这里分析的源码... -
Vue3中的Vue Router初探
2020-05-07 17:13:12随着新版本的Vue Router处于Alpha阶段,我们已经可以开始查看下一个版本的Vue中它是如何工作的。 Vue3中的许多更改都会稍微改变我们访问插件和库的方式,其中包括Vue Router。我们将结合使用Alpha版本的Vue Router和... -
Vue router获取所有路由
2021-08-29 18:09:35console.log(router.options.routes); -
Vue router 重定向 redirect 如何传值
2021-01-12 18:01:23配置 vue_router 时, 很经常就用到重定向(redirect)功能 例如: 没登录重定向到登录页面(导航卫士拦截也是高效的登录检查方法) index, home, house 重定向到首页等 这些不需要传参的情况, 直接设置为目标地址的字符串...