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);
    }
},
相关推荐
EricWang13588 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning8 分钟前
React.lazy() 懒加载
前端·react.js·前端框架
web行路人18 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱00119 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼92137 分钟前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂40 分钟前
ajax关于axios库的运用小案例
前端·javascript·ajax
长弓三石1 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙
小马哥编程1 小时前
【前端基础】CSS基础
前端·css
嚣张农民1 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员
周亚鑫1 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf