gpt4 book ai didi

万字血书Vue—路由

转载 作者:我是一只小鸟 更新时间:2023-03-19 14:31:59 33 4
gpt4 key购买 nike

多个路由通过路由器进行管理.

前端路由的概念和原理

(编程中的) 路由 (router)就是一组 key-value 对应关系,分为:后端路由和前端路由 。

后端路由 指的是: 请求方式、请求地址 和 function处理函数 之间的 对应关系 。

在SPA程序中, 所有组件的展示和切换 都在这唯一的一个页面内完成,此时, 不同组件之间的切换 需要通过 前端路由 来实现 。

通俗易懂的来说, 前端路由 是: Hash地址 (url中#的部分)与 组件 之间的对应关系 。

前端路由的工作方式

  • 用户 点击了 页面上的路由链接
  • 导致了 URL地址栏 中的 Hash值 发生了变化
  • 前端路由监听到了Hash地址的变化
  • 前端路由把当前 Hash地址对应的组件 渲染到浏览器中

image

实现简易的前端路由(底层实现原理)

App.vue根组件 。

                        
                          <template>
  <div>
    <h1>这是App根组件</h1>
    <a href="#/Home">Home</a>&nbsp;
    <a href="#/Movie">Movie</a>&nbsp;
    <a href="#/About">About</a>&nbsp;
    <hr>

    <component :is="comName"></component>
  </div>
  
</template>

<script>
import MyHome from './MyHome.vue'
import Mymovie from './MyMovie.vue'
import MyAbout from './MyAbout.vue'
import { walkFunctionParams } from '@vue/compiler-core'

export default {
    name:'App',
    components:{
        MyHome,
        MyAbout,
        Mymovie,
    },
    data(){
        return{
            comName:'MyHome'
        }
    },
    created(){
        window.onhashchange=()=>{
            switch(location.hash){
                case '#/Home':
                    this.comName='MyHome'
                    break
                 case '#/Movie':
                    this.comName='MyMovie'
                    break
                 case '#/About':
                    this.comName='MyAbout'
                    break
            }
        }
    }

}
</script>

<style lang="less" scoped>

</style>

                        
                      

vue-router的基本使用

vue-router 是vue.js官方给出的 路由解决方案 ,它只能结合vue项目进行使用,能够轻松的管理SPA项目中的组件切换.

  • vue-router 3.x 只能结合vue2进行使用,官方文档: https://router.vuejs.org/zh/
  • vue-router 4.x 只能结合vue3进行使用,官方文档: https://next.router.vuejs.org/

二者差异主要是在声明router配置文件上.

vue-router 3.x的基本使用步骤

  • 在项目中安装vue-router
                        
                          npm install vue-router@3.5.2 -S

                        
                      
  • src 源代码目录下,新建 router/index.js 路由模块
                        
                          //导入包
import Vue from 'vue'
import VueRouter from 'vue-router'
//插件引入
Vue.use(VueRouter)
//创建路由的实例对象
const router = new VueRouter
//向外共享
export default router

                        
                      
  • 在入口文件 main.js 中引入
                        
                          import router from '@/router/index.js'
......
new Vue({
    ...
    router:router
    ...
}).$mount('#app')

                        
                      

vue-router 4.x的基本使用步骤

  • 在项目中安装vue-router
                        
                          npm install vue-router@next -S

                        
                      
  • 定义路由组件

MyHome.vue、MyMovie.vue、MyAbout.vue 。

  • 声明 路由链接 占位符

可以使用 <router-link> 标签(会被渲染成a链接)来声明 路由链接 ,并使用 <router-view> 标签来声明 路由占位符 。

                        
                          <template>
  <div>
    <h1>这是App根组件</h1>
   <!--  <a href="#/Home">Home</a>&nbsp;
    <a href="#/Movie">Movie</a>&nbsp;
    <a href="#/About">About</a>&nbsp; -->
      
   <!-- 声明路由链接 -->
    <router-link to="/home">首页</router-link>
     <router-link to="/movie">电影</router-link>
      <router-link to="/about">我的</router-link>
    <hr>
   <!-- 路由占位符 -->
   <router-view></router-view>
    <component :is="comName"></component>
  </div>
  
</template>

                        
                      
  • 创建 路由模块

从项目中 创建router.js 路由模块,按照以下四步:

从vue-router中按需导入两个方法 。

                          
                            import { createRouter, createWebHashHistory } from 'vue-router'
//createRouter方法用于创建路由的实例对象
//createWebHashHistory用于指定路由的工作方式(hash模式)

                          
                        

导入需要使用路由控制的组件 。

                          
                            import MyHome from './MyHome.vue'
import MyMovie from './MyMovie.vue'
import MyAbout from './MyAbout.vue'

                          
                        

创建路由实例对象 。

                          
                            const router = createRouter({
history: createWebHashHistory(),
routes: [
  {
      path: '/home', component: MyHome
  },
  {
      path: '/movie', component: MyMovie
  },
  {
      path: '/about', component: MyAbout
  },

]
})

                          
                        

向外共享路由实例对象 。

                          
                            export default router

                          
                        

在main.js中导入并挂载路由模块 。

                          
                            import { createApp } from 'vue'
import App from './App.vue'
import './index.css'

import router from './components/router'

const app = createApp(App)
//挂载路由写法
app.use(router)
app.mount('#app')


                          
                        
  • 导入并挂载 路由模块

vue-router的高级用法

路由重定向

指的是:用户在访问 地址A 的时候, 强制用户跳转 到地址C,从而展示特点的组件页面 。

通过路由规则的 redirect 属性,指定新的路由地址 。

                        
                          const router = createRouter({
    history: createWebHashHistory(),
    routes: [
        {
            path: '/home', component: MyHome
        },
        {
            path: '/',redirect:'/home' //访问根路径会重定向到home组件
        },
        {
            path: '/movie', component: MyMovie
        },
        {
            path: '/about', component: MyAbout
        },

    ]
})

                        
                      
路由传参

query 参数 。

                        
                          <router-link :to="/about/home/message?id=123&title='abc'">我的</router-link>

<router-link :to="{
                 path:'/about/home/message',
                 query:{
                 	id:123,
                 	title:'abc'
                 }
               }">
    我的
</router-link>

                        
                      

params 参数 。

声明时:

                        
                          path:'/about/home/message/:id/:title'

                        
                      
                        
                          <router-link :to="/about/home/message/123/abc">我的</router-link>

<router-link :to="{
                 name:'my',
                 params:{
                 	id:123,
                 	title:'abc'
                 }
               }">
    我的
</router-link>

                        
                      

this.$route 是路由的"参数对象" 。

this.$router 是路由的"导航对象" 。

路由高亮
  • 使用 默认 的高亮class类名

被激活 的路由链接,默认会使用r outer-link-active 的类名,开发者可以使用此类名选择器,为激活的路由链接设置高亮样式 。

  • 自定义 路由高亮的class类

在创建路由的实例对象时,开发者可以基于linkActiveClass属性,自定义类名 。

                        
                          const router = createRouter({
    history: createWebHashHistory(),
    linkActiveClass:'active-router',
    routes: [
        {
            path: '/home', component: MyHome
        },
        {
            path: '/',redirect:'/home' //访问根路径会重定向到home组件
        },
        {
            path: '/movie', component: MyMovie
        },
        {
            path: '/about', component: MyAbout
        },

    ]
})

                        
                      
嵌套路由

通过路由来实现 组件的嵌套展示 。

步骤:

  • 声明子路由链接和子路由占位符
                        
                          <template>
  <div>MyAbout组件</div>
  <hr>
  <router-link to="/about/tab1">tab1</router-link>&nbsp;
  <router-link to="/about/tab2">tab2</router-link>

  <router-view></router-view>
</template>

                        
                      
  • 在父路由规则中,通过 children 属性 嵌套声明 子路由规则
                        
                          const router = createRouter({
    history: createWebHashHistory(),
    routes: [
        {
            path: '/home', component: MyHome
        },
        {
            path: '/movie', component: MyMovie
        },
        {
            path: '/about', component: MyAbout,children:[
                {
                path:'tab1',component:Tab1
            },
            {
                path:'tab2',component:Tab2
            },
        ]
        },

    ]
})

                        
                      

子路由规则的path不要以/开头 。

在嵌套路由中实现路由的重定向 。

                        
                          const router = createRouter({
    history: createWebHashHistory(),
    routes: [
        {
            path: '/home', component: MyHome
        },
        {
            path: '/movie', component: MyMovie
        },
        {
            path: '/about',
            component: MyAbout,
            redirect:'/about/tab1',
            children:[
                {
                path:'tab1',component:Tab1
            },
            {
                path:'tab2',component:Tab2
            },
        ]
        },

    ]
})

                        
                      
动态路由匹配

指的是:把Hash地址中 可变的部分 定义为 参数项 ,从而 提高路由规则的复用性 ,在vue-router中使用 英文冒号: 来定义路由的参数 。

                        
                            {   
      path: '/movie/:id', component: MyMovie
   },

                        
                      

获取动态路由参数值的方法:

  • $route.params参数对象
                        
                          <template>
  <div>Mymovie组件---{{$route.params.id}}</div>
  
</template>

                        
                      
  • 使用props接受路由参数
                        
                          {
     path: '/movie/:id', component: MyMovie,
     props: true,
},

                        
                      

为了简化路由参数的获取形式 ,vue-router允许在 路由规则 中 开启props传参 。

编程式导航

通过调用API实现导航的方式,叫做 编程式导航 ,与之对应的,通过点击链接实现导航的方式,叫做 声明式导航 .

  • 普通网页中点击a链接,vue项目中点击 <router-link> 都属于声明式导航
  • 平台网页中调用 location.herf 跳转到新页面的方式,属于编程式导航

vue-router中编程式导航API 。

  • this.$router.push('hash地址') 跳转到指定Hash地址,并 增加 一条历史记录,从而展示对应的组件。
  • this.$router.replace('hash地址') 跳转到指定Hash地址,并 替换 当前的历史记录,从而展示对应的组件。
  • this.$router.go('数值n') 实现导航历史的前进、后退(-1),超过最大层数,则原地不动。

$router.back() 后退到上一层页面 。

$router.forward() 前进到下一层页面 。

命名路由

通过name属性为路由规则 定义名称 ,叫做命名路由, name值不能重复,具有唯一性 。

Hash地址特别长时体现出命名路由的优势 。

  • 使用命名路由实现声明式导航
                        
                          <template>
	<h3>
        MyHome组件
    </h3>
    <router-link :to="{name:'mov',params:{id : 3}}">goToMovie</router-link>
</template>

<script>
	export default {
        name:'MyHome',
    }
</script>

                        
                      
  • 使用命名路由实现编程式导航
                        
                          <template>
	<h3>
        MyHome组件
    </h3>
	<button @click="goToMovie(3)">
        goToMovie
    </button>
</template>

<script>
	export default {
        method: {
            goToMovie(id) {
                this.$router.push({name:'mov',params:{id : 3}})
            }
        }
    }
</script>

                        
                      
导航守卫

导航守卫 可以 控制路由的访问权限 。

image

如何声明全局的导航守卫 。

全局的导航守卫会 拦截每个路由规则 ,从而对每个路由都进行 访问权限 的控制 。

                        
                          const router = createRouter({
   ...
})
//调用路由实例对象的beforeEach函数,fn必须是一个函数吗,每次拦截后,都会调用fn进行处理
//声明全局的导航守卫,fn称为守卫方法
router.beforeEach(fn)
    
router.beforeEach(()=>{
    console.log('Ok')
})


                        
                      

守卫方法的三个形参(可选) 。

                        
                          router.beforeEach((to,from,mext)=>{
    console.log('Ok')
    //to 目标路由对象(信息)
    //from当前导航正要离开的路由对象
    //next 是一个函数,表示放行
})

                        
                      

注:

在守卫方法中不声明next形参,则 默认允许用户访问每一个路由 。

在守卫方法中声明了next形参,则 必须调用next()函数 ,否则不允许用户访问如何一个路由! 。

next函数 的3种调用方式 。

                        
                          //声明全局的导航守卫
router.beforeEach((to, from, next) => {
    if (to.path === '/main') {
        //证明用户要访问后台主页  
        next(false)//强制用户停留在之前所处的组件
        next('login')//强制用户调转到指定页面
    } else {
        //证明用户要访问的不是后台主页 
        next()
    }
})

                        
                      

结合token 控制后台主页的访问权限 。

                        
                          router.beforeEach((to, from, next) => {
    const tokenStr = localStorage.getItem('token') //读取token


    if (to.path === '/main' && !tokenStr) { //token不存在,需要登录
        //证明用户要访问后台主页  
       // next(false)//强制用户停留在之前所处的组件
        next('login')//强制用户调转到指定页面
    } else {
        //证明用户要访问的不是后台主页 
        next()
    }
})


                        
                      

Hash&History

路由器的两种工作模式: hash & history .

对于 url 来说:#及后面的内容就是 hash 值, hash 值不会带给服务器.

hash 模式:

  1. 地址中永远带着 # 号,不美观;
  2. 若地址校验严格,会被标记为不合法;
  3. 兼容性较好;

history 模式

  1. 地址干净,美观;
  2. 兼容性比 hash 模式较差;
  3. 应用部署上线需要后端支持,解决刷新页面服务端404问题;( node 可以使用 connect-history-api-fallback

最后此篇关于万字血书Vue—路由的文章就讲到这里了,如果你想了解更多关于万字血书Vue—路由的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com