自学内容网 自学内容网

Vue篇-06

1、路由简介

vue-rooter:是vue的一个插件库,专门用来实现SPA应用

1.1、对SPA应用的理解

1、单页 Web 应用(single page web application,SPA)。
2、整个应用只有一个完整的页面 index.html。
3、点击页面中的导航链接不会刷新页面,只会做页面的局部更新
4、数据需要通过 ajax 请求获取。

1.2、什么是路由?

1、路由就是一组映射关系(key - value),多个路由需要路由器(router)进行管理。
2、key 为路径, value 可能是 function 或 component组件
3、vue 的一个插件库(vue-router),专门用来实现 SPA 应用

1.3、路由的分类

1.3.1、前端路由

1、key是路径,value是组件component,用于展示页面内容。
2、工作过程:当浏览器的路径改变时, 对应的组件就会显示。

1.3.2、后端路由 

1、key是路径,value 是 function, 用于处理客户端提交的请求。(node.js)
2、工作过程:服务器接收到一个请求时, 根据请求路径找到匹配的函数来处理请求, 返回响应数据。

2、基本使用

Vue2安装vue-router,命令:npm i vue-router@3
Vue3安装vue-router,命令:npm i vue-router

 2.1、编写路由配置项 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
       }
   ]
});

2.2、引入配置项并使用插件 main.js

//引入Vue
import Vue from "vue";
//引入App
import App from './App';
//引入vue-router
import VueRouter from "vue-router";
import router from './router';

//关闭Vue的生产提示
Vue.config.productionTip = false;

//应用vue-router插件
Vue.use(VueRouter);

new Vue({
    el: '#app',
    render: h => h(App),
    router
});

2.3、实现路由切换App.vue

使用<router-link></router-link>标签实现路由的切换 ,to=“/xxx”是展示的路径, active-class是当点击部分的时候可展示的效果(高亮样式)

<!--原始使用a标签跳转多个页面,多页面应用-->
<!--<a class="list-group-item active" href="./about.html">About</a>-->
<!--<a class="list-group-item" href="./home.html">Home</a>-->

<!--vue中借助router=link标签实现路由的切换-->
<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>

完整的App.vue

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header"><h2>Vue Router Demo</h2></div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!--原始使用a标签跳转多个页面,多页面应用-->
<!--          <a class="list-group-item active" href="./about.html">About</a>-->
<!--          <a class="list-group-item" href="./home.html">Home</a>-->
          <!--vue中借助router=link标签实现路由的切换-->
          <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>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <!--router-view确定视图的位置-->
            <router-view>
            </router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
}
</script>
<style lang="css" scoped>

</style>

 2.4、指定展示的位置

决定组件展示的位置

<router-view></router-view>

2.5、注意点

1、路由组件通常存放在src/pages文件夹,一般组件通常存放在src/components文件夹。一般组件就按我们之前用法那么用,路由组件的话就是靠<router-link></router-link>标签关联上index.js里配置的路由规则,然后由<router-view></router-view>放到指定位置。

2、通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。所以切换的时候,路由组件一直是 其他的销毁-当前的挂载 => 其他的销毁-当前的挂载 =>. … …

3、每个组件都有自己的$route属性,里面存储着自己的路由信息。
4、整个应用只有一个router,可以通过组件的$router属性获取到

   

$route:每个组件的route都不一样

$router:整个应用的router都是一样的,且只有一个

三、嵌套(多级)路由

3.1、创建子组件

路由组件创建在pages中,创建News.vueMessage.vue

News.vue

<template>
    <ul>
      <li>news001</li>
      <li>news002</li>
      <li>news003</li>
    </ul>
  </template>
  
  <script>
  export default {
    name: "News"
  }
  </script>
  
  <style scoped>
  
  </style>

Message.vue

<template>
    <div>
      <ul>
        <li>
          <a href="/message1">message001</a>&nbsp;&nbsp;
        </li>
        <li>
          <a href="/message2">message002</a>&nbsp;&nbsp;
        </li>
        <li>
          <a href="/message/3">message003</a>&nbsp;&nbsp;
        </li>
      </ul>
    </div>
  </template>
  
  <script>
  export default {
    name: "Message"
  }
  </script>
  
  <style scoped>
  
  </style>

3.2、路由的children配置项

router/index.js

//该文件专门用于创建整个应用的路由器

import VueRouter from "vue-router";
import About from "@/pages/About";
import Home from '@/pages/Home';
import News from "@/pages/News";
import Message from "@/pages/Message";

//创建并默认暴露一个路由器
export default new VueRouter({
   routes:[
       {
           path:'/about',
           component: About
       },
       {
           path:'/home',
           component: Home,
           children:[
               {
                   path: 'news',
                   component: News
               },
               {
                   path: 'message',
                   component: Message
               }
           ]
       }
   ]
});

3.3、模板上写路由跳转

App.vue不变,套娃是套在home里,写在Home.vue中

要写完整路径而且加斜杠,例如:

<router-link to="/home/news">News</router-link>

App.vue

<template>
  <div>
    <div class="row">
      <Banner/>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!--原始使用a标签跳转多个页面,多页面应用-->
<!--          <a class="list-group-item active" href="./about.html">About</a>-->
<!--          <a class="list-group-item" href="./home.html">Home</a>-->
          <!--vue中借助router=link标签实现路由的切换-->
          <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>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <!--router-view确定视图的位置-->
            <router-view>
            </router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Banner from "@/components/Banner";
export default {
  name: "App",
  components: {Banner},
}
</script>
<style lang="css" scoped>

</style>

Home.vue

<template>
    <div>
      <h2>我是Home的内容</h2>
      <div>
        <ul class="nav nav-tabs">
          <li>
            <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
          </li>
          <li>
            <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
          </li>
        </ul>
        <router-view>
        </router-view>
      </div>
    </div>
  </template>
  
  <script>
  export default {
    name: "Home",
    // mounted() {
    //   console.log('Home组件挂载完毕', this);
    //   window.homeRoute = this.$route;
    //   window.homeRouter = this.$router;
    // },
    // // beforeDestroy() {
    // //   console.log('Home组件将要被销毁');
    // // }
  }
  </script>
  
  <style scoped>
  </style>

 四、路由的query参数

query参数是在组件的$route上的一个东西,可以用来接收数据,类似的还有params参数

4.1、传参的方式

  1. :to中使用字符串拼接或者模板字符串,直接写在要转到的路由路径后面,使用?连接,&拼接
  2. :to中使用对象的形式传参(推荐使用)

Message.vue

<ul>
      <li v-for="m in messageList" :key="m.id">
        <!---跳转路由并携带query参数,to的字符串写法-->
        <!--<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{ m.title }}</router-link>&nbsp;&nbsp;-->
        <!---跳转路由并携带query参数,to的对象写法-->
        <router-link
            :to="{
              path:'/home/message/detail',
              query:{
                id: m.id,
                title: m.title
              }
        }">
          {{ m.title }}
        </router-link>&nbsp;&nbsp;
      </li>
    </ul>

4.2、接收参数

Detail.vue【使用$route.query来接收】

<template>
    <ul>
      <li>消息编号:{{ $route.query.id }}</li>
      <li>消息标题:{{ $route.query.title }}</li>
    </ul>
 </template>
 
 <script>
 export default {
   name: "Detail",
   mounted() {
     console.log(this.$route);
   }
 }
 </script>
 
 <style scoped>
 
 </style>

4.3、配置三级路由

router/index.js

//该文件专门用于创建整个应用的路由器

import VueRouter from "vue-router";
import About from "@/pages/About";
import Home from '@/pages/Home';
import News from "@/pages/News";
import Message from "@/pages/Message";
import * as path from "path";
import Detail from "@/pages/Detail";

//创建并默认暴露一个路由器
export default new VueRouter({
   routes:[
       {
           path:'/about',
           component: About
       },
       {
           path:'/home',
           component: Home,
           children:[ //通过children配置子级路由
               {
                   path: 'news', //二级路由不加斜杠
                   component: News
               },
               {
                   path: 'message', //二级路由不加斜杠
                   component: Message,
                   children:[
                       {
                           path: 'detail', //三级路由
                           component: Detail
                       }
                   ],
               }
           ]
       }
   ]
});

五、命名路由

作用:可以简化路由的跳转。
使用:先命名,使用name属性,然后简化后可以直接通过名字跳转,比较方便。
注意:传参时字符串写法没法这么用

router/index.js

//该文件专门用于创建整个应用的路由器

import VueRouter from "vue-router";
import About from "@/pages/About";
import Home from '@/pages/Home';
import News from "@/pages/News";
import Message from "@/pages/Message";
import Detail from "@/pages/Detail";

//创建并默认暴露一个路由器
export default new VueRouter({
   routes:[
       {
           name: 'regard',
           path:'/about',
           component: About
       },
       {
           path:'/home',
           component: Home,
           children:[
               {
                   path: 'news',
                   component: News
               },
               {
                   path: 'message',
                   component: Message,
                   children:[
                       {
                           name: 'particulars',
                           path: 'detail',
                           component: Detail
                       }
                   ],
               }
           ]
       }
   ]
});

六、路由的params参数

套娃时传数据不只可以用query参数,也可以用params参数,params也是$route上的一部分

6.1、配置路由,声明接收params参数

占位符的名字要和传的params参数的属性名一致,否则url会不显示

{
    path:"/home",
    component :Home,
    children:[
        {
            path:'news',
            component:News
        },
        {
            component:Message,
            children:[
                {
                    name:'xiangqing',
                    path:'detai1/:id/:title',//使用占位符声明接收params参数
                    component:Detail   
                }
            ]
        }
    ]
}

6.2、传递参数

方法一:
<!--跳转并携带params参数,to的字符串写法-->
<router-link :to="/home/message/detail/666/你好">跳转</router-link>

方法二:
<!--跳转并携带params参数,to的对象写法-->
<router-link
    :to="{
        name:'xiangqing',
        params:{
            id:666,
            title:'你好'
        }
    }"

>跳转</router-link>

特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!

6.3、接收参数

<ul>
    <li>消息编号:{{ $route.params.id }}</li>
    <li>消息标题:{{ $route.params.title }}</li>
</ul>

七、路由的props数据

让路由组件更方便的收到参数

7.1、写法1:死数据

值为对象,该对象中的所有key-value都会以props的形式传给Detail组件
缺点:这样值是死的

7.2、写法2:props:true

props值为布尔值,若布尔值为真,就会把该路由组件收到的params参数,以props的形式传给Detail组件
缺点:只能传params参数的,query参数不能用这个

7.3、写法3:函数

props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件,这个是最常用的,函数会受到参数,这个参数就是组件身上的$route,可以通过它来获取query或者params里面的东西,然后传过去

八、router-link的replace属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式
  2. 浏览器的历史记录有两种写入方式:分别为push和replacepush是追加历史记录,replace是替换当前记录。路由跳转时候默认为push
  3. 如何开启replace模式:<router-link replace .......>News</router-link>

  • 如果用的是默认的push,点击进入到下一个路由的时候可以返回到上一个路由
  • 如果用的是replace,点击进入到下一个路由的时候,浏览器左上角不会有返回上一步

九、编程时路由导航 

9.1、这是什么?

不借助<router-link>实现路由跳转,让路由跳转更加灵活

主要是用$router的两个api :pushreplace,来实现路由跳转,push是默认带缓存,replace是覆盖缓存

9.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()//可前进也可后退

 

十、缓存路由组件

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

// 缓存一个用字符串
<keep-alive include="News"> 
    <router-view></router-view>
</keep-alive>


 // 缓存多个路由组件用 数组 (使用 `v-bind`) 
<keep-alive :include="['News', 'Message']">
     <router-view></router-view>
</keep-alive>

缓存的名字是组件名,在需要被缓存组件的外侧包裹keep-alive,不要去被缓存组件的template里边包

示例: 

 

像图中<keep-alive include="News">这么写的话,切换到MessageNews不会销毁

但是从Message切换到NewsMessage会销毁。

十一、两个新的生命周期钩子函数

  • 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
  • 具体名字:
    • activated 路由组件被激活时触发,(从没有出现在你面前–>组件出现在你眼前)。 相当于mounted
    • deactivated 路由组件失活时触发。类似于beforeDestroy
  • 除了这些钩子,还有个钩子是nextTick,是在页面挂载完且数据放到页面上后执行的钩子
<template>
  <ul>
    <li :style="{opacity}">欢迎学习vue</li>
    <li>news001 <input type="text"/></li>
    <li>news002 <input type="text"/></li>
    <li>news003 <input type="text"/></li>
  </ul>
</template>

<script>
export default {
  name: "News",
  data(){
    return {
      opacity: 1
    }
  },
  // mounted() {
  //   this.timer = setInterval(() => {
  //     console.log('@')
  //     this.opacity -= 0.01;
  //     if(this.opacity <= 0) this.opacity = 1;
  //   },16);
  // },
  //
  // beforeDestroy() {
  //   console.log('News组件将要被销毁');
  //   clearInterval(this.timer);
  // },

  //激活(路由组件独有的两个钩子)
  activated() {
    console.log('News组件被激活');
      this.timer = setInterval(() => {
        console.log('@')
        this.opacity -= 0.01;
        if(this.opacity <= 0) this.opacity = 1;
      },16);
  },
  //失活
  deactivated() {
    console.log('News组件失活了');
    clearInterval(this.timer);
  }
}
</script>

<style scoped>

</style>

十二、路由守卫

作用:对路由进行权限控制(想让看哪个,不想让看哪个)
分类:全局守卫、独享守卫、组件内守卫


12.1、路由元信息

配置路由规则时专门提供的一个容器meta,用来存放我们自定义的一些属性


12.2、全局路由守卫


12.2.1、全局前置守卫

初始化时执行、每次路由切换前执行

使用下面的api,有三个参数,:to到哪里去,from从哪里来,next下一步(放行)

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

 其中router是自定义的路由规则的名字const router = new VueRouter({})

要设置只有本地存储中school为hznu的可以查看新闻和消息,那就要在前置路由守卫中设置,如果符合条件,才能放行。

//初始化时,或每一次路由切换之前都会调用一个函数
router.beforeEach((to, from, next) => {
    console.log('前置路由守卫,外边的保安', to, from);
    //to是往哪去的对象,from的从哪来的对象,都包括name和path
    // if (to.name === 'xinwen' || to.name === 'xiaoxi') {
    if (to.meta.isAuth) {   //判断是否需要鉴权
        if (localStorage.getItem('school') === 'hznu') {
            next();  //放行
        } else {
            alert('学校名不对,无权限查看!');
        }
    } else {
        next(); //放行
    }
});


12.2.2、全局后置守卫


12.3、独享路由守卫


12.4、组件内路由守卫


12.4.1、进入组件时


12.4.2、离开组件时


12.4.3、以about为例


12.5、组件从前置路由守卫到失活的执行流程

文章部分内容参考:

GitHub - Panyue-genkiyo/vue-advance: 利用vue-cli脚手架学习vue核心知识(示例小项目)

Vue2(十三):路由的使用及注意点、嵌套路由、路由的query和params参数、props配置_vue2 路由加query-CSDN博客


原文地址:https://blog.csdn.net/Yvonne_hjj/article/details/145044440

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!