19- vue-router路由

本文详细介绍了VueRouter在Vue3中的基本使用,包括路由配置、组件导航、query和params参数、命名路由、props传递、路由模式(history和hash)以及守卫功能。
摘要由CSDN通过智能技术生成

vue-router

  1. 路由的基本使用
    • npm i vue-router@3 Vue2是版本3 ,Vue3是版本4

    • main.js 中
      import router from ‘./router’;
      Vue.use(VueRouter)

    • 创建 src > router > index.js

      // 该文件专门用于创建整个应用的路由器
      import VueRouter from 'vue-router'
      //引入组件
      import About from '../components/About'
      import Home from '../components/Home'
      
      //创建并暴露一个路由器
      export default new VueRouter({
      	routes:[
      		{
      			path:'/about',
      			component:About
      		},
      		{
      			path:'/home',
      			component:Home
      		}
      	]
      })
      
    • 修改跳转链接, 注意 active-class , to=“/home”

      <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
      <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
      
    • 修改引用的地方

      <!-- 指定组件的呈现位置 -->
      <router-view></router-view>
      
  2. $route 属性
    • 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹。
    • 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
    • 每个组件都有自己的$route属性,里面存储着自己的路由信息。
    • 整个应用只有一个router,可以通过组件的$router属性获取到
  3. 多级路由
    //创建并暴露一个路由器
    export default new VueRouter({
    	routes:[
    		{
    			path:'/about',
    			component:About
    		},
    		{
    			path:'/home',
    			component:Home,
    			children:[
    				{
    					path:'news',
    					component:News,
    				},
    				{
    					path:'message',
    					component:Message,
    				}
    			]
    		}
    	]
    })
    

    router-link to的写法路径要完整

    <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
    
  4. 路由的query参数
    1. 子组件获取query参数 {{$route.query.id}}

    2. 父组件传递参数

      • <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>
        
      • <!-- 跳转路由并携带query参数,to的对象写法 -->
        <router-link :to="{
            path:'/home/message/detail',
            query:{
                id:m.id,
                title:m.title
            }
        }">
           {{m.title}}
        </router-link>
        
  5. 命名路由

    对于比较多级的子路径,可以给一个name属性,简化路由的路径

    {
        path: 'message',
        component: MyMessage,
        children: [
            {
                name: 'detail',
                path: 'detail',
                component: MyDetails
            }
        ]
    }
    

    使用:

    <li v-for="m in messages" :key="m.id">
        <router-link :to="{
            name: 'detail',
            query: {
                id: m.id,
                title: m.title
            }
        }">{{m.title}}</router-link>&nbsp;&nbsp;
    </li>
    
  6. 路由的params参数
    1. router配置:

      children: [
          {
              name: 'detail',
              path: 'detail/:id/:title',//占位
              component: MyDetails
          }
      ]
      
    2. 使用:

      <li v-for="m in messages" :key="m.id">
      <router-link :to="{
          name: 'detail',
          params: {
              id: m.id,
              title: m.title
          }
      }">{{m.title}}
      
    3. 注意:当使用parmas时,路径一点只能用name,不能用path

    4. 获取:

      <h3>ID是:{{$route.params.id}}</h3>
      <h3>Title是:{{$route.params.title}}</h3>
      
  7. 路由的props配置
    1. router.js文件

      {
      	name:'xiangqing',
      	path:'detail/:id',
      	component:Detail,
      
      	//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
      	// props:{a:900}
      
      	//第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
      	// props:true
      	
              //第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
      	props(route){
      		return {
      			id:route.query.id,
      			title:route.query.title
      		}
      	}
      }
      
    2. VC 里面使用

      <template>
        <div>
          <h3>ID是:{{id}}</h3>
          <h3>Title是:{{title}}</h3>
        </div>
      </template>
      
      <script>
      export default {
          name: 'MyDetails',
          props:['id', 'title']
      }
      
  8. router-link的push&&replace属性
    push`是追加历史记录,`replace`是替换当前记录。路由跳转时候默认为`push
    <router-link replace class="list-group-item" active-class="active" to="/home/news">News</router-link>
    
  9. 编程式路由导航
    1. 作用:不借助<router-link>实现路由跳转,让路由跳转更加灵活

    2. 具体编码:

      //$router的两个API
      this.$router.push({
          name:'xiangqing',
              params:{
                  id:xxx,
                  title:xxx
              }
      })
      this.$router.replace({
          name:'xiangqing',
              params:{
                  id:xxx,
                  title:xxx
              }
      })
      this.$router.forward() //前进
      this.$router.back() //后退
      this.$router.go() //可前进也可后退,里面的参数是正的时候就是前进的步数,负就是后退的
      
  10. 缓存路由组件

    1. 作用:让不展示的路由组件保持挂在,不被销毁。

    2. <keep-alive include="News">
      	<router-view></router-view>
      </keep-alive>
      
  11. 两个新的生命周期钩子

    1. 作用:路由组件所独有的两个钩子,用于捕获路由组件是激活状态
    2. 具体名字:
      1. activated 路由组件被激活时触发
      2. deactivated 路由组件失活时触发
  12. 路由守卫

    1. 1 全局路由守卫

      1. 作用:对路由进行权限控制

      2. 分类:全局守卫、独享守卫、组件内守卫

      3. 全局前置路由守卫,(初始化、每次切换路由之前进行校验)

        //全局前置守卫:初始化时执行、每次路由切换前执行
        router.beforeEach((to,from,next)=>{
        	if(to.name === 'xinwen'){ //判断当前路由是否需要进行权限控制
        		if(localStorage.getItem('school') === 'atguigu'){ //权限控制的具体规则
        			next() //放行
        		}else{
        			alert('暂无权限查看')
        			// next({name:'guanyu'})
        		}
        	}else{
        		next() //放行
        	}
        })
        
      4. 但是路径判断可能会很复杂,所以改进

        //router配置修改
        children:[
            {
                name:'xinwen',
                path:'news',
                component:News,
                meta:{isAuth:true,title:'新闻'} //加meta
            },
        ]
        // 修改判断
        if(to.meta.isAuth){ //判断是否需要鉴权
        
      5. 全局后置路由守卫 (没有next)

        //全局后置守卫:初始化时执行、每次路由切换后执行
        router.afterEach((to,from)=>{
        	if(to.meta.title){ 
        		document.title = to.meta.title //修改网页的title
        	}else{
        		document.title = 'vue_test'
        	}
        })
        
        // 另外修改title,需要把 index.html title 改 <title>硅谷系统</title>
        
    2. 2 独享路由守卫

      1. 写在router路径配置里面, 只对 某一个路由验证,而 beforeEach 是对每一个路由进行验证

      2. 只有前置,没有后置

        children:[{
            name:'xinwen',
            path:'news',
            component:News,
            meta:{isAuth:true,title:'新闻'}, //加meta
            beforeEnter(to,from,next){
              if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
                if(localStorage.getItem('school') === 'atguigu'){
                      next()
                   }else{
                        alert('暂无权限查看')
                        // next({name:'guanyu'})
                    }
                }else{
                    next()
                }
            }
        }]
        
        //可结合全局后置路由守卫使用
        router.afterEach((to,from)=>{
        })
        
    3. 3 组件内路由守卫

      1. 经过路由规则才能校验

      2. 写在组件内部

        //进入守卫:通过路由规则,进入该组件时被调用
        beforeRouteEnter (to, from, next) {
        },
        //离开守卫:通过路由规则,离开该组件时被调用
        beforeRouteLeave (to, from, next) {
        }
        
  13. 路由模式
    history模式与hash模式

    1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。

    2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。

    3. hash模式:

      • 地址中永远带着#号,不美观
      • 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
      • 兼容性较好。
    4. history模式:

      • 地址干净,美观 。
      • 兼容性和hash模式相比略差。
      • 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
    5. 在 router里面配置

      const router =  new VueRouter({
      	mode:'history', // history 没有# ,hash有#
      	routes:[...]
      })
      
    6. history模式与hash模式上线区别

      • 打包部署文件 npm run build 生成了一个dist文件夹,生成了js,css, html等打包文件

      • 创建服务器 npm i express

      • node创建一个服务器 server.js

        const express = require('express')
        const history = require('connect-history-api-fallback');
        
        cosnt app = express()
        Vue.use(history)
        
        app.use(express.static(__dirname+'/static'))
        
        app.get('/person', (req, res) => {
            res.send({
                name: 'tome',
                age: 18
            })
        })
        
        app.listen(5005, (err) => {
            if(!err) console.log('服务器启动成功了!')
        })
        
      • 创建文件夹 static 或者 public, 把打包出来的文件放进去

      • 打包之后history模式直接访问server.js不存在的路径会报错 404

      • hash模式—hash值不会带给服务器不会报错

      • 解决方案 npmjs.com 有个工具 connect-history-api-fallback,正则匹配解决问题

      • https://www.npmjs.com/package/connect-history-api-fallback

        npm i connect-histroy-api-fallback

      • 或者找后端工程师解决这个问题,还有一个这个解决404问题 nginx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值