VUE 入门及应用 ( 路由 router )

6.前端路由 router

Vue Router | Vue.js 的官方路由 (vuejs.org)

官方地址 : https://router.vuejs.org/zh/

6.1.基本配置

6.1.0.准备 MyPage.vue

创建 用于测试 vue文件 ../views/MyPage.vue

vue 复制代码
<template>
  <div>
    <h1>MyPage</h1>
  </div>
</template>

<script >

</script>

<style scoped lang="scss">

</style>

6.1.1.基本配置

src / router / index.js 路由文件

js 复制代码
const routes = [
    {
    	path: '请求路径',
    	name: '名称',
    	component: 对应组件, 需要引入组件
  	},
    ...
]

如果想引入新的资源, 写好First.vue 文件

先在 src / router / index.js 路由文件中添加引入组件

js 复制代码
// 引入 组件
import MyPage from '../views/MyPage.vue'

再增加 路由信息

js 复制代码
{
    path: '/myPage',
    name: 'myPage',
    component: MyPage,
},

6.1.2.导航标签/显示标签

<router-link to="/path" >说明</router-link> 导航标签, 相当于html中的 <a> , 其中的 to 属性 相当于 href 属性

<router-view></router-view> 显示标签, 相当于 html中的 <iframe> 用于显示

在 App.vue 页面中应用

html 复制代码
<template>
  <div id="app">
      <!-- 导航, router-link  相当于<a>  to属性 相当于 href -->
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <router-link to="/myPage">MyPage</router-link>
    </div>
      <!-- 显示区, 根据导航显示不同的内容 -->
    <router-view></router-view>
  </div>
</template>

6.2.子路由(多级路由/嵌套路由)

6.2.1.创建两个vue文件

在 src / views 中添加 两个 vue 文件

/views/Page1.vue Page1.vue

vue 复制代码
<template>
  <div>
    <h1>page1</h1>
  </div>
</template>

<script >

</script>

<style scoped lang="scss">

</style>

/views/Page1.vue Page2.vue

vue 复制代码
<template>
  <div>
    <h1>page2</h1>
  </div>
</template>

<script >

</script>

<style scoped lang="scss">

</style>

6.2.2.配置子路由

修改 src / router / index.js 路由文件中添加引入组件

js 复制代码
import Page1 from '@/views/Page1.vue'
import Page2 from '@/views/Page2.vue'

修改 路由配置, 增加 children 属性 ,

注意 子路由配置 path 时, 前面没有 / 斜杠 page1 , page2

也可以 写 全路径 /myPage/page1 , /myPage/page2

js 复制代码
  {
    path: '/myPage',
    name: 'myPage',
    component: MyPage,
    children:[
      {
        path: 'page1',
        name: 'Page1',
        component: Page1,
      },
      {
        path: 'page2',
        name: 'Page2',
        component: Page2,
      }
    ]
  },
6.2.3.修改 MyPage.vue 文件

在 MyPage.vue 文件中

增加 用于路由跳转的 <router-link></router-link> 及用于显示的 <router-view></router-view>

vue 复制代码
<template>
  <div>
    <h1>MyPage</h1>

    <div >
      <div style="float: left; width: 200px; height: 500px; background: aliceblue;">
        <div id="nav">
          <router-link to="/myPage/page1" active-class="active">页面1</router-link>
          <br/> <br/>
          <router-link to="/myPage/page2" active-class="active">页面2</router-link>
        </div>
      </div>
      <div   style="float: left; width: 800px; height: 500px; background: #eeeeee; border-radius: 5px;"  >
        <router-view></router-view>
      </div>
    </div>

  </div>
</template>

<style scoped lang="scss">
.active {
  color: red;
}
</style>

6.3.相关概念

6.3.1.两种工作模式

在 Vue.js 中,Vue Router 提供了两种不同的路由模式:hash 和 history。

6.3.1.1.Hash 模式:
  • 当使用 hash 模式时,URL 的路径部分会包含一个 #(哈希)符号,以及随后的路由标识符。例如,http://example.com/#/user/home

  • #(哈希)符号 后面的内容不会在请求时发给服务器

  • 浏览器通过监听 hashchange 事件来检测 URL 哈希值的变化,并且由于哈希变化不会导致页面重新加载,所以这种模式对旧版浏览器兼容性较好。

  • 在 Vue Router 中配置为 hash 模式的方法是:

    javascript 复制代码
    const router = new VueRouter({
      mode: 'hash',
      routes: [...]
    });
6.3.1.2.History 模式:
  • History 模式利用 HTML5 History API 来实现 URL 路径的变化,这样生成的 URL 就像正常的页面 URL,没有 # 符号。例如,http://example.com/user/home

  • 使用此模式时,当用户点击浏览器的前进、后退按钮或者直接修改地址栏中的 URL,Vue Router 可以监听到这些变化并作出相应调整。

  • 然而,为了使服务器能够正确处理这些 URL 请求而不返回 404 错误,在部署应用时需要配置服务器,使其将所有未命中静态资源请求都指向应用的入口文件(通常是 index.html)。

  • 在 Vue Router 中配置为 history 模式的方法是:

    javascript 复制代码
    const router = new VueRouter({
      mode: 'history',
      routes: [...]
    });

总结来说,hash 模式简单易用,但 URL 显示不够优雅;history 模式提供更自然的 URL 结构,但需要额外的服务器端配置支持。

根据项目需求和开发环境选择合适的路由模式。

6.3.2.路由对象

route : 表示一条路由, 就是一组 标识 key ( 路径path ) 对应一组组件 component 或者 函数 function

  • route 对象表示当前活动的路由信息。当你导航到应用中的某个路径时,Vue Router 会解析这个 URL,并创建一个对应的 route 对象。

  • 这个对象包含了从 URL 解析出的详细信息,如:path(当前路由路径)、params(动态路由参数)、query(查询参数)、name(命名路由的名字)等。

  • 在 Vue 组件内部,可以通过 this.$route 访问当前活跃的 route 对象。

  • routes 表示一组路由

6.3.3.路由器

router : 它是一个机制, 充当管理路由的管理者角色.

  • router 是一个全局可用的 Vue Router 实例,它是整个应用路由系统的管理者和控制中心。
  • 通过调用 Vue.use(VueRouter) 安装路由插件后,我们可以创建并配置一个 router 实例,定义应用的所有路由规则以及他们的组件映射、嵌套路由、重定向、命名路由等功能。
  • router 提供了许多方法来操纵应用程序的路由状态,比如:
    • router.push(location):将当前位置更改为给定的新位置。
    • router.replace(location):类似于 push,但是不会向历史记录添加新条目。
    • router.go(n):在浏览器的历史记录中向前或向后移动指定的步数。
    • router.resolve(location):解析给定的位置,返回一个描述如何到达该位置的对象。
  • 我们通常在 Vue 应用初始化阶段通过 new VueRouter() 创建 router 实例,并将其注入到根 Vue 实例的 router 属性上。
  • this.$router 表示全局路由器对象

6.3.4.vue文件分类

组件 : 在vue文件中 通过 import导入, 并使用 components 声明的 通常当成 组件, 存放在 components 文件中

页面 : 通过路由访问的vue文件通常当成页面, 存放在 views , pages 等文件夹中

6.4.路由传值

6.4.1.query方式

query方式,可以在地址栏可以看到参数 , 相当于url?传参

6.4.1.1.基本写法

/views/AboutView.vue 增加 两组 <router-link> 标签 ,

分别以 字符串及json 格式 进行传参

vue 复制代码
    <router-link to="/myPage?id=123&title=标题">MyPage query</router-link>
    <br>
    <router-link :to="{
      path: '/myPage',
      query: {
        id: 123,
        title: '标题'
      }
    }">MyPage query json</router-link>

/views/MyPage.vue 的 mounted 函数中通过 this.$route 接收传递来的值

js 复制代码
mounted() {
    console.log(this.$route)
}

可以在控制台 可以 看到 query打印 内容

js 复制代码
fullPath: "/myPage?id=123&title=%E6%A0%87%E9%A2%98"
hash: ""
matched: [{...}]
meta: {}
name: "myPage"
params: {}
path: "/myPage"
query: {id: '123', title: '标题'}
[[Prototype]]: Object
6.4.1.2.传对象信息

/views/AboutView.vue 增加 data信息

dd 对象 , 包括 id, title 两个属性

js 复制代码
data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      dd:{
        id: 666,
        title: '对象的标题'
      }
    }
  }

template 中增加 新的 <router-link> 标签 ,

并使用`` 反引号` 进行 模板接值

html 复制代码
 <br>
<router-link :to="`/myPage?id=${dd.id}&title=${dd.title}`">MyPage query dd</router-link>

这样就可以传递动态信息

6.4.2.params

params方式, 在地址栏 看不到参数

但要 在路由的 index.js 文件中 path属性后面追加 :标识 用于设置传值的标识

6.4.2.0.准备MyPage2.vue

增加新的 /views/MyPage2.vue 文件

vue 复制代码
<template>
  <h1>MyPage2</h1>
</template>
<script >
  export default {
    name: 'MyPage2',
    mounted() {
      console.log(this.$route)
    }
  }
</script>

在路由的 index.js 文件中引入文件

js 复制代码
import MyPage2 from '../views/MyPage2.vue'

增加路由配置, 在 路由后追加了 :id , :title

js 复制代码
{
 	path: '/myPage2/:id/:title',
    name: 'myPage2',
    component: MyPage2,
},
6.4.2.1.基本写法

/views/AboutView.vue 增加 <router-link> 标签 ,

html 复制代码
<br>
<router-link :to="`/myPage2/${dd.id}/${dd.title}`">MyPage2 params </router-link>

/views/MyPage2.vue 的 mounted函数中通过 this.$route 接收传递来的值

可以在控制台看到, params 接收到值

text 复制代码
fullPath: "/myPage2?id=123&title=%E6%A0%87%E9%A2%98"
hash: ""
matched: [{...}]
meta: {}
name: "myPage2"
params: {id: '666', title: '对象的标题'}
path:"/myPage2/666/对象的标题"
query: {}
[[Prototype]]: Object
6.4.2.2.params 对象传值

/views/AboutView.vue 增加 <router-link> 标签 , 通过json 格式传值

这里要注意 在使用 params 传值时 , 要使用 name 来设置路由目标

html 复制代码
<br>
<router-link :to="{
                  name: 'myPage2',
                  params: {
                  	id: dd.id,
                  	title: dd.title
                  }
                }">MyPage2 params json</router-link>

6.4.3.props

在 路由的index.js 文件中 通过 props 来设置接值

6.4.3.0.准备MyPage3.vue

增加新的 /views/MyPage3.vue 文件

vue 复制代码
<template>
  <h1>MyPage3</h1>
</template>
<script >
  export default {
    name: 'MyPage3',
    mounted() {
      console.log(this.$route)
    }
  }
</script>

在路由的 index.js 文件中引入文件

js 复制代码
import MyPage3 from '../views/MyPage3.vue'

增加路由配置, 在 路由后追加了 :id , :title

js 复制代码
{
 	path: '/myPage3',
    name: 'myPage3',
    component: MyPage3,
},
6.4.3.1. 值为对象

该对象中的所有key-value都会以props的形式传给目标组件

修改路由index.js中的配置:

js 复制代码
{
        path: '/myPage3',
        name: 'myPage3',
        component: MyPage3,
        props:{id:1,title:'hello'}
}

/views/MyPage3.vue 文件 增加 props 接值

vue 复制代码
<template>
  <div>
    <h1>MyPage3</h1>

    <h2>{{id}}</h2>
    <h2>{{title}}</h2>
  </div>

</template>
<script >
  export default {
    name: 'MyPage3',
    props: ["id", "title"],

    mounted() {
      console.log(this.$route)
    }
  }
</script>

这种方式 只能接收到 配置文件中的固定值

6.4.3.2.值为布尔值

若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给目标组件。

修改路由index.js 文件 配置

js 复制代码
{
        path: '/myPage3/:id/:title',
        name: 'myPage3',
        component: MyPage3,
        props:true
}

/views/AboutView.vue 增加 <router-link> 标签 ,

html 复制代码
<br>
<router-link :to="`/myPage3/${dd.id}/${dd.title}`">MyPage3 params </router-link>

这里注意 只能 针对 params 传值 方式有效

6.4.3.3.值为函数

通过 函数参数进行传值 , 这时 对 query, params 参数 都可以转换成 props 信息

修改路由index.js 文件 配置

js 复制代码
{
        path: '/myPage3/:id/:title',
        name: 'myPage3',
        component: MyPage3,
		props($route){
     		return {
             id:$route.params.id,
             title:$route.params.title,
    	 }
 		}
 }

6.5.编程式路由

编程式路由是指通过编程( js 代码 )的方式来操作和控制路由的跳转

6.5.1.push

this.$router.push(path) : 该方法用于将当前历史记录推入一个新条目。调用 router.push 会将应用从当前路径跳转到指定的新路径。

6.5.1.1.基本跳转

/views/AboutView.vue 增加 <button> 按钮 并 增加事件

html 复制代码
<br>
<button @click="goMyPagePush">转到 MyPage  push</button>

在 methods 中增加处理函数

js 复制代码
 methods: {
    goMyPagePush(){
      this.$router.push('/myPage')
    }
  }
6.5.1.2.跳转query传值

/views/AboutView.vue 增加 <button> 按钮 并 增加事件

html 复制代码
<br>
<button @click="goMyPagePush2">转到 MyPage  push 2</button>

在 methods 中增加处理函数

js 复制代码
goMyPagePush2(){
    this.$router.push({
        path: '/myPage',
        query: {
            id: 123,
            title: '标题'
        }
    })
},
6.5.1.3.跳转params传值

/views/AboutView.vue 增加 <button> 按钮 并 增加事件

html 复制代码
<br>
<button @click="goMyPage2Push3">转到 MyPage2  push 3</button>

在 methods 中增加处理函数, 这里可以使用name , 也可以使用 path

js 复制代码
goMyPage2Push3(){
    this.$router.push({
        // name: 'myPage2',
        path: '/myPage2/:id/:title',
        params: {
            id: 123,
            title: '标题'
        }
    })
},

6.5.2.replace

类似于 push,但它不会向浏览器的历史栈添加新的记录,而是替换当前的记录。

6.5.2.1.测试跳转

/views/AboutView.vue 增加 <button> 按钮 并 增加事件

html 复制代码
<br>
<button @click="goMyPageReplace">转到 MyPage replace</button>
<br>
<button @click="goMyPageReplace2">转到 MyPage  replace 2</button>
<br>
<button @click="goMyPage2Replace3">转到 MyPage2  replace 3</button>

在 methods 中增加处理函数, 这里可以使用name , 也可以使用 path

json 复制代码
goMyPageReplace(){
    this.$router.replace('/myPage')
},
goMyPageReplace2(){
    this.$router.replace({
        path: '/myPage',
        query: {
            id: 123,
            title: '标题'
        }
	})
},
goMyPage2Replace3(){
    this.$router.replace({
        // name: 'myPage2',
        path: '/myPage2/:id/:title',
            params: {
            id: 123,
            title: '标题'
        }
    })
}

6.5.3.比较

this.$router.pushthis.$router.replace 都是 Vue Router 提供的编程式导航方法,用于在单页面应用中进行路由切换。它们的主要区别在于浏览器历史记录和后退操作:

  1. this.$router.push()

    • 当调用 this.$router.push(path)this.$router.push({ path: '...' }) 时,会将当前路由添加到浏览器的历史栈中。
    • 这意味着用户点击浏览器的"后退"按钮时,他们将返回到之前的页面。
  2. this.$router.replace()

    • 而当调用 this.$router.replace(path)this.$router.replace({ path: '...' }) 时,不会向浏览器的历史栈添加新的条目。
    • 相反,它会替换当前的路由条目,因此当用户点击"后退"按钮时,他们将直接跳转到上一个(再上一个)页面,而不是回到使用 replace 方法替换掉的那个页面。

总结来说:

  • 如果你希望用户的导航动作可以回溯,就使用 push
  • 如果你想实现类似于重定向的效果,使得新页面加载后用户不能通过点击后退按钮返回原页面,则使用 replace

6.5.4.历史跳转

类似于 BOM中的 history

vue-two/src/views/MyPage.vue

/views/MyPage.vue 增加 <button> 按钮 并 增加事件

html 复制代码
<div>
    <button @click="goBackGo">go(-1)</button>
    <button @click="goBack">back</button>
    <button @click="goForward">forward</button>
    <button @click="goForwardGo">go(1)</button>
</div>

在 methods 中增加处理函数, 测试可知与浏览器的前进后退按钮产生相同的效果

json 复制代码
methods: {
    goBack() {
        this.$router.back()
    },
    goForward() {
        this.$router.forward()
    },
    goBackGo() {
        this.$router.go(-1)
    },
    goForwardGo() {
        this.$router.go(1)
    }
}

6.6.路由缓存及事件

6.6.1.<keep-live>标签

默认情况下 , 当切换路由后, 原有组件是被销毁的

6.6.1.1.销毁前函数监听

修改 /views/Page1.vue 增加 name组件名 及 销毁前函数

vue 复制代码
<template>
  <div>
    <h1>page1</h1>
  </div>
</template>

<script >
  export default {
    name: 'Page1',
    beforeDestroy() {
      console.log('page1 beforeDestroy')
    },
  }
</script>

修改 /views/Page2.vue 增加 name组件名 及 销毁前函数

vue 复制代码
<template>
  <div>
    <h1>page2  <input type="text"> </h1>
  </div>
</template>

<script >
  export default {
    name: 'Page2',
    beforeDestroy() {
      console.log('page2 beforeDestroy')
    },
  }
</script>

在 MyPage.vue 组件中 点击 page1, page2 进行切换时, 发现每一次切换对应的组件都会调用 销毁前函数

6.6.1.2.<keep-live>标签

修改 在 /views/MyPage.vue 组件, 在 显示标签 <router-view></router-view> 外 增加 <keep-live>标签

html 复制代码
 <keep-alive  >
   <router-view></router-view>
 </keep-alive>

然后再测试, 就会发现 点击 page1, page2 进行切换时, 不会 再 调用 销毁前函数, 表明page1, page2 两个组件并没有被销毁

6.6.1.3. include , exclude 属性

<keep-live>标签 上可以增加 include , exclude 属性, 分别 来指定哪些组件需要缓存或不需要缓存

属性的值为 各组件的名

多个使用, 连接

只对 Page1 组件进行缓存

html 复制代码
<keep-alive  include="Page1" >
	<router-view></router-view>
</keep-alive>

不对 Page1组件进行缓存

html 复制代码
<keep-alive  exclude="Page1">
<router-view></router-view>
</keep-alive>

6.6.2.缓存路由事件

当一个 不被 销毁的组件, 被激活, 或者失活时, 分别对应两个钩子函数

js 复制代码
activated() {
    // 激活函数
  console.log('page1 activated')
},
deactivated() {
    // 失活函数
  console.log('page1 deactivated')
}

6.7.路由守卫(拦截器)

Vue 2 中提供了多种路由守卫(Route Guards),它们是钩子函数,允许在路由切换的过程中进行拦截,

根据需要决定是否允许导航发生、如何发生以及在导航完成后执行特定的操作。

6.7.1.前置守卫

也叫, 全局前置守卫:在编写在 路由index.js文件中

  • router.beforeEach((to, from, next) => {})

  • 这个守卫发生在每次路由即将改变前,参数 tofrom 分别表示目标路由和当前路由对象,而 next 是一个函数,调用它才能进行下一步操作。

  • 可以使用 next() 来继续导航,next(false) 来取消当前导航,或 next('/other/path') 跳转到其他路径。

js 复制代码
//全局前置路由守卫------------初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to,from,next)=>{
    console.log('前置路由守卫',to,from)
    if(to.query.id == null ){ //判断条件
        console.log('跳转时没有传id')
        next()
    }else{
        next(false)
    }
})

判断跳转时, 是否向目标组件以 query形式传递 id , 没有可以继续跳转, 传递了 就不能跳转

6.7.2.全局解析守卫

全局解析守卫:

  • router.beforeResolve((to, from, next) => {})
  • 类似于 beforeEach,但会在所有异步依赖项完成之后,但在渲染之前被调用,适合处理异步数据获取并基于这些数据决定是否继续导航。

6.7.3.后置守卫

也叫, 全局后置守卫:

  • router.afterEach((to, from) => {})
  • 这个守卫发生在每次路由切换成功之后,不支持中断,主要用于记录路由历史、页面标题设置等操作。
js 复制代码
//全局后置路由守卫------------初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to,from)=>{
    console.log('后置路由守卫',to,from)
    console.log('跳转成功后 做点什么')
})

6.7.4.独享守卫

也叫 , 路由独享前置守卫: 写在路由配置项中

  • 通常在定义路由时,在路由配置的 meta 字段中添加自定义属性,并在路由文件或者全局路由配置的地方使用 beforeEnter 守卫:
json 复制代码
{
    path: 'page1',
    name: 'Page1',
    component: Page1,
    meta:{isAuth:false},
    beforeEnter: (to, from, next) => {
        console.log('独享路由守卫',to,from)
        if(to.meta.isAuth){ //判断是否需要鉴权
            next()
        }else{
            next(false)
        }
    }
},

6.7.4.组件内守卫

编写在组件内的钩子函数

6.7.4.1.组件内的路由进入守卫:
  • 使用 beforeRouteEnter 生命周期钩子:进入该组件时被调用

先在 路由 index.js 文件中 为 MyPage2组件增加 meta属性

json 复制代码
{
    path: '/myPage2/:id/:title',
    name: 'myPage2',
    component: MyPage2,
    meta:{isAuth:true}
}

再在 MyPage2 组件中增加钩子函数, 进入到当前组件时调用

javascript 复制代码
//通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
    console.log('About--beforeRouteEnter',to,from)
    // 不可以直接访问 this,因为此时组件实例还没创建
    // 可以通过传入回调函数来访问组件实例
    if(to.meta.isAuth){
        next(v=>{
            console.log("next-route:", v.$route)
        })
    }else{
        next(false)
    }
},
6.7.4.2.组件内的路由更新守卫:
  • 当路由改变导致组件复用且组件对应的路由参数发生变化时触发:
javascript 复制代码
beforeRouteUpdate(to, from, next) {
    // 在这个钩子中,可以访问组件实例 `this`
    // 并可以对响应式数据进行更改
    console.log(this.$route)
    next();
},
6.7.4.3.组件内的路由离开守卫:
  • 在导航离开该组件的对应路由时触发:
javascript 复制代码
 //通过路由规则,离开该组件时被调用
beforeRouteLeave(to, from, next) {
    // 确保在用户离开前保存数据或取消某项操作
    const answer = window.confirm('是否想离开?');
    if (answer) {
        console.log('About--beforeRouteLeave',to,from)
        next();
    } else {
        next(false);
    }
},
相关推荐
Neweee1 分钟前
JavaScript进阶内容详解
前端
大鸡爪2 分钟前
Vue3 组件库实战(五):Icon 图标组件的设计与实现
前端·vue.js
bluceli2 分钟前
前端测试实战指南:构建高质量代码的完整体系
前端·测试
行走的陀螺仪3 分钟前
前端公共库开发保姆级路线:从0到1复刻VueUse官方级架构(pnpm+Turbo+VitePress)
前端·架构
顽固_倔强3 分钟前
深入理解 Vue3 数据绑定实现原理
前端·面试
前端付豪3 分钟前
组件拆分重构 App.vue
前端·架构·代码规范
Wect4 分钟前
React 更新触发原理详解
前端·react.js·面试
cxxcode4 分钟前
Web 帧渲染与 DOM 准备
前端
光影少年4 分钟前
React Hooks的理解?常用的有哪些?
前端·react.js·掘金·金石计划
大鸡爪5 分钟前
Vue3 组件库实战(七):从本地到 NPM:版本管理与自动化发布指南(下)
前端·vue.js