0


【Vue】Vue的路由

一、Vue的路由

1.路由(routing)

路由是指从源页面到目的页面时,决定端到端路径的决策过程。

2.前端路由

前端路由即由前端来维护一个路由规则。实现模式有两种:

  • 利用URL的Hash模式:就是常说的锚点,JavaScript通过 hashChange事件来监听URL的改变。(IE7及以下版本需要使用轮询)。在地址中以’#'分隔页面。
  • 利用HTML5的History模式:它使用URL看起来像普通网站一样,在地址中以’/'分隔页面。但是页面并没有跳转。这种模式需要服务器端支持,服务端在接收到所有的请求后,都指向同一个HTML文件,不然会出现页面错误。

3.VueRouter路由

路由就是根据一个请求路径选中一个组件进行渲染的决策过程。VueRouter路由是Vue官方推出的路由管理器。

  • route:表示单个路由。
  • routes:表示多个路由的集合。是一个数组,在这个数组中包含了多个route。
  • router:译为路由器,是route、routes的管理者。

路由的查找过程是: router --> routes --> route(当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由)

4.VueRouter的组成

5.VueRouter常用的函数

  • createRouter函数:创建路由器
  • createWebHashHistory函数:创建Hash模式的路由
  • createWebHistory函数:创建History模式路由
//例如:

//1.创建路由器
Const router = createRouter({
    //2.指定Hash模式或History模式的页面路由
    history: createWebHashHistory(),
    //3.创建路由集合
    routes: [
    //4.一个个的route
    // .......
    ],
})

二、VueRouter的使用

1、安装vue-router

    npm install vue-router     (前提:先在webstorm创建并配置vue项目)

2、创建路由文件

  • 定义路由表:routes,在路由表中包含多个route
  • 创建路由器:router,在路由器中指定路由表(routes)以及路由模式(hash/history)
// 引入vue-router
import {createRouter, createWebHashHistory, createWebHistory} from "vue-router";
import Home from "../components/Home.vue";
import About from "../components/About.vue";

//定义路由表
const routes = [   
    {
        path:'/home',
        component: Home,
        name: 'home'
    },
    {
        path:'/about',
        component: About,
        name: 'about'
    }
]

//定义路由器
const router = createRouter({
    routes,
    history: createWebHistory()
})

//导出路由器
export default router;

3、声明路由请求接口

  • 路由链接组件(router-link)为用户提供了提交路由请求的交互接口。使用to属性来声明链接组件的目标路径,当用户点击链接组件时,组件向路由器提交向目标路径的路由请求。

  • 在模板中,使用<router-link>标签声明路由链接元素。

  • 例如,下面的示例声明了一个目标路径为/about的路由链接:

      <router-link to=“/about”>ABOUT</router-link>
    
      注意:上例中的“/about”必须在路由表中出现。
    

4、声明路由出口

  • 路由视图组件(router-view)为路由器($router)提供了所选中组件的渲染出口。

  • 在模板中,使用标签<router-view>声明路由视图元素。

  • 例如,下面示例在模板中声明了一个路由视图:

      <router-view></router-view>
    

** components目录下的Home.vue组件代码段:**

<template>
  <h2>我是home组件</h2>
</template>

<script>
export default {
  name: "Home"
}
</script>

<style scoped>

</style>

** components目录下的About.vue组件代码段:**

<template>
  <h2>我是About组件</h2>
</template>

<script>
export default {
  name: "About"
}
</script>

<style scoped>

</style>

routers目录下的router.js文件:

import {createRouter, createWebHashHistory, createWebHistory} from "vue-router";
//引入两个组件
import Home from "../components/Home.vue";
import About from "../components/About.vue";
const rs = [   //定义路由表
    {
        path:'/home',
        component: Home,
        name: 'home'
    },
    {
        path:'/about',
        component: About,
        name: 'about'
    }
   
]

//定义路由器
const router = createRouter({
    routes:rs,
    history: createWebHistory()
})

//导出路由器
export default router

main.js代码段:

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './routers/router'

const app=createApp(App)

app.use(router)

app.mount('#app')

App.vue代码段:

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
<!--创建路由的链接组件(路由接口)-->
  <div>
    <router-link to="/home">Home</router-link>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <router-link to="/about">About</router-link>
  </div>
  <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
  <router-view></router-view>
</template>

效果图:

三、动态路由

是指路由器能够自动地建立自己的路由表,并且能够根据实际情况的变化适时地进行调整。

在路由中带有路由参数,路由参数会设置到’$route.params’中。

1.动态路由的路径格式

动态路由的路径格式:/组件名/:参数名;在组件中通过’$route.params.参数名’获取参数。

App.vue代码段:

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
<!--创建路由的链接组件(路由接口)-->
  <div>
    <router-link to="/user/项羽">动态路由---项羽</router-link>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <router-link to="/user/刘邦">动态路由---刘邦</router-link>
 </div>
  <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
  <router-view></router-view>
</template>

User.vue组件代码段:

<template>
<h2>User组件</h2>
  <p>欢迎回来,{{ $route.params.name }}</p>
</template>
<script>
export default {
  name: "User"
}
</script>

routers目录下的router.js文件:

import {createRouter, createWebHashHistory, createWebHistory} from "vue-router";
import User from "../components/User.vue";
const rs = [   //定义路由表
   {
        path: '/user/:name',
        component: User,
        name:'user'
    } 
]
//定义路由器
const router = createRouter({
    routes:rs,
    history: createWebHistory()
})

//导出路由器
export default router

效果图:

2.在URL中带查询参数

在URL中带查询参数:/组件名?参数名=参数值;在组件中通过’$route.query.参数名’获取参数

App.vue代码段:

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
<!--创建路由的链接组件(路由接口)-->
  <div>
    <router-link to="/library?id=1">图书1</router-link>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <router-link to="/library?id=2">图书2</router-link>
</div>
  <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
  <router-view></router-view>

</template>

Library.vue组件代码段:

<template>
  <h2>Library组件</h2>
  <p>图书:{{ $route.query.id }}</p>
</template>

<script>
export default {
  name: "Library"
}
</script>

routers目录下的router.js文件:

import {createRouter, createWebHashHistory, createWebHistory} from "vue-router";
import Library  from "../components/Library.vue";
const rs = [   //定义路由表
  {
        path: '/library',
        component: Library,
        name:'library'
    }
]
//定义路由器
const router = createRouter({
    routes:rs,
    history: createWebHistory()
})

//导出路由器
export default router

3.通配符匹配

通配符匹配:'*'表示匹配所有路径。通常用于匹配前端的404页面

四、嵌套路由

在组件中包含子组件的情况.vue官方提供children属性来定义这种嵌套关系。该属性是 一个数组,本质就是路由表。

举一个实例:图书组件的嵌套

(1)图书列表组件:显示图书标题,每个标题都是链接组件,当用户点击链接组件(一级路由组件Books.vue)时,跳转到二级路由组件(Book.vue)

(2)图书组件:显示图书的详细信息

静态资源assets目录下的book.js文件:

export  default[
    {
        id:1,
        title:'Vue.js无难事',
        desc:'前端框架经典图书'
    },
    {
        id:2,
        title:'React.js工程师宝典',
        desc:'前端框架经典图书'
    },
    {
        id:3,
        title:'Go语言程序设计',
        desc:'最流行的脚本语言'
    }
]

Books.vue组件代码段:

<template>
  <div>
    <h2>图书列表</h2>
    <ul>
      <li v-for="book in bookList" :key="book.id">
        <router-link :to="'/books/book/'+book.id">{{ book.title }}</router-link>
      </li>
    </ul>
  </div>
  <hr/>
  <div>
    <router-view></router-view>
  </div>
</template>
<script>
import books from "../assets/books";
export default {
  name: "Books",
  data(){
    return {
      bookList:books
    }
  }
}
</script>

<style scoped>
li{
  list-style-type: none;
  margin-top: 25px;
}
</style>

Book.vue组件代码段:


<template>
  <div>
    <p>图书ID:{{book.id}}</p>
    <p>图书名称:{{ book.title }}</p>
    <p>描述:{{ book.desc }}</p>
  </div>
</template>

<script>
import books from "../assets/books";
export default {
  name: "Book",
  data(){
    return {
      book: {}
    }
  },
  created() {//获取第一次渲染时的数据,否则第一次渲染时$route对象得不到数据
    this.book = books.find((item)=>item.id == this.$route.params.id)
  },
  watch : {
    '$route':{  //监听路由参数的变化
      handler:function (to){
        this.book = books.find((item)=>item.id == this.$route.params.id)
      }
    }
  }
}
</script>

routers目录下的router.js文件:

注意:component: ()=>import(‘…/components/Books.vue’)另一种引入组件的写法

import {createRouter, createWebHashHistory, createWebHistory} from "vue-router";
const rs = [   //定义路由表
  {
        path: '/books',
        name: 'books',
        component: ()=>import('../components/Books.vue'),
        children: [{
            path: '/books/book/:id',
            component: ()=>import('../components/Book.vue')
        }]
    }
]
//定义路由器
const router = createRouter({
    routes:rs,
    history: createWebHistory()
})

//导出路由器
export default router

效果图:

五、命名路由

有时通过一个名称来标识路由会更方便,特别是在链接到路由,或者是执行导航时。可以创建Router实例时, 在routes选项中为路由设置名称。

例如:将上例中的App.vue修改后同样可以的到相同的跳转效果

App.vue代码段:

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
<!--创建路由的链接组件(路由接口)-->
  <div>
    //<router-link to="/home">Home</router-link>
    //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    //<router-link to="/about">About</router-link>
    <router-link :to="{name:'home'}">Home</router-link>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <router-link :to="{name:'about'}">About</router-link>
  </div>
  <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
  <router-view></router-view>
</template>

效果图:

六、命名视图

命名视图:给路由视图()一个名称,可以将组件渲染到指定名称的路由视图中。

1.给路由视图添加name属性

例如上例的books.vue代码段修改如下:

<template>
  <div>
    <h2>图书列表</h2>
    <ul>
      <li v-for="book in bookList" :key="book.id">
        <router-link :to="'/books/book/'+book.id">{{ book.title }}</router-link>
      </li>
    </ul>
  </div>
  <hr/>
  <div>
    <router-view name="test"></router-view>
  </div>
  <hr/>
  <div>
    <router-view name="bookDetail"></router-view>
  </div>
</template>

<script>
import books from "../assets/books";
export default {
  name: "Books",
  data(){
    return {
      bookList:books
    }
  }
}
</script>

<style scoped>
li{
  list-style-type: none;
  margin-top: 25px;
}
</style>

2.在路由表中,指定components属性的值

例如routers目录下的router.js文件:

  {
        path: '/books',
        name: 'books',
        component: ()=>import('../components/Books.vue'),
        children: [{
            path: '/books/book/:id',
            //component: ()=>import('../components/Book.vue')
            components:{
            test:()=>import('../components/Book.vue')
            }
        }]
    }

因为指定的路由视图是test,所以将会渲染到视图name为test上,也就是第一个 横线的下方,第二个横线的上方。(如果为bookDetail,则在第二条线的下方)

七、导航守卫

1.路由导航的方式

  • 标签导航:<router-link to=“url”></router-link>
  • 编程式导航:this.$router.push(url)

2.导航守卫

在导航过程中由权限验证、数据的获取等业务的需要,会出现页面的重定向。

每个导航守卫都有三个参数(to,from,next)

‘to’:到哪里去
‘from’:从哪里来
‘next’:下一步去哪儿

(1)全局前置守卫:使用router.beforeEach注册,当一个导航触发时,前置守卫就会按路由规则进行匹配调用。保证next函数能够正常运行
Login.vue代码段:

<template>
  <div>
    <h2>用户登录</h2>
    <div>
      <label>
        UserName:
        <input type="text" v-model.trim="username"/>
      </label>
      <br><br>
      <label>
        PassWord:
        <input type="password" v-model.trim="password"/>
      </label>
      <br><br>
      <button type="button" @click.prevent="login">登录</button>
    </div>
    <h3>{{ info }}</h3>
  </div>
</template>

<script>
export default {
  name: "Login",
  data() {
    return {
      username: '',
      password: '',
      info: ''
    }
  },
  methods:{
    login(){
      if ("lisi"=== this.username && "12345"===this.password){ //合法用户,将用户信息写入页面缓存中
        sessionStorage.setItem("isAuth",true);
        this.info = "";

        if (this.$route.query.redirect){ //合法用户请求页面参数存在,就进行页面跳转
          let redirect = this.$route.query.redirect
          this.$router.replace(redirect);
        }else{
          this.$router.replace('/home');
        }
      }else{
        sessionStorage.setItem('isAuth',false)
        this.username = ''
        this.password = ''
        this.info = '用户名或密码错误'
      }
    }
  }
}
</script>
<style scoped>
</style>

Home.vue代码段:

<template>
<h2>我是首页</h2>
</template>

<script>
export default {
  name: "Home"
}
</script>

<style scoped>

</style>

main.js代码段(全局注册router):

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './routers/index.js'
const app = createApp(App)
app.use(router)
app.mount('#app')

router文件下的路由index.js文件:

import { createRouter,createWebHistory } from 'vue-router';
import Home from '../components/Home.vue';
import Login from '../components/Login.vue';

const rs = [
    {
        path:'/home',
        name:'home',
        component:Home
    },
    {
        path:'/login',
        name:'login',
        component:Login
    }
]

const router = createRouter({
    routes:rs,
    history:createWebHistory()
})
//创建导航前置守卫
router.beforeEach((to,from,next)=>{
    if(to.path == '/login'){ //若访问登录页面,则放行
        next();
    }else{
        if(sessionStorage.getItem('isAuth')){//若用户已登录,则放行
            next();
        }else{
            //用户没有登录,并且要访问受保护的资源,则将登录组件的地址告诉给next函数
            next({
                path:'/login',
                query:{
                    redirect:to.fullPath
                }
            })
            console.log(to.fullPath)
        }
    }
})
export default router;

App.vue代码段:

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import HelloWorld from './components/HelloWorld.vue'
import Login from './components/Login.vue'
</script>

<template>

  <img src="/vite.svg" class="logo" alt="Vite logo" />
 <router-link :to="{name:'login'}" class="login">登录</router-link>
  <router-view> </router-view>

</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
.login{
  display: flex;
  justify-content:center;
}
</style>

效果图:


本文转载自: https://blog.csdn.net/weixin_51481135/article/details/126427504
版权归原作者 早睡早起长头发 所有, 如有侵权,请联系我们删除。

“【Vue】Vue的路由”的评论:

还没有评论