Vue路由(vue-router)详细讲解_vue router-程序员宅基地

技术标签: 前端  vue.js  javascript  

中文文档:https://router.vuejs.org/zh/

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。路由实际上就是可以理解为指向,就是我在页面上点击一个按钮需要跳转到对应的页面,这就是路由跳转;

首先我们来学习三个单词(route,routes,router):

  route:首先它是个单数,译为路由,即我们可以理解为单个路由或者某一个路由;

  routes:它是个复数,表示多个的集合才能为复数;即我们可以理解为多个路由的集合,JS中表示多种不同状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;所以我们记住了,routes表示多个数组的集合;

  router:译为路由器,上面都是路由,这个是路由器,我们可以理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由;

我们结合一个小demo来看(文章有点长,耐心慢慢看,学得慢才能进步的快,当然可以跟着一起敲):

  首先需要安装vue-cli来构建一个vue的开发环境(怎么安装这里不讲,自己百度去,如果这种问题自己都解决不了的话,后面的知识可能对你来说收益不大)

  安装完vue-cli之后,我们的项目目录结构如下:

 然后我们在命令行中输入npm install vue-router -g来安装vue-router,安装完之后我们可以打开package.json文件,在package.json文件中可以看到vue-router的版本号;

 到这一步我们的准备工作就完成了,要进行写demo了;

我们在src目录下新建三个文件,分别为page1.vue和page2.vue以及router.js:

page1.vue:

<template>
    <div>
        <h1>page1</h1>
        <p>{
   {msg}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                msg: "我是page1组件"
            }
        }
    }
</script>

 page2.vue:

<template>
    <div>
        <h1>page2</h1>
        <p>{
   {msg}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                msg: "我是page2组件"
            }
        }
    }
</script>

router.js

//引入vue
import Vue from 'vue';
//引入vue-router
import VueRouter from 'vue-router';
//第三方库需要use一下才能用
Vue.use(VueRouter)
//引用page1页面
import page1  from './page1.vue';
//引用page2页面
import page2  from './page2.vue';

//定义routes路由的集合,数组类型
const routes=[
    //单个路由均为对象类型,path代表的是路径,component代表组件
    {path:'/page1',component:page1},
    {path:"/page2",component:page2}
]

//实例化VueRouter并将routes添加进去
const router=new VueRouter({
//ES6简写,等于routes:routes
    routes
});

//抛出这个这个实例对象方便外部读取以及访问
export default router

这里我们再修改一下main.js

import Vue from 'vue'
import App from './App'
//引用router.js
import router from './router.js'
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
//一定要注入到vue的实例对象上
  router,
  components: { App },
  template: '<App/>'
})

修改App.vue

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div>
//router-link定义页面中点击触发部分  
      <router-link to="/page1">Page1</router-link>
      <router-link to="/page2">Page2</router-link>
    </div>
//router-view定义页面中显示部分
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

就这样,我们的页面就可以进行路由跳转和切换了,路由的基本使用就完成了;但是有个问题就是我们第一次进去是看不到路由页面的,这是因为我们没有设置默认值,我们首次进入的时候路径是为空的,那么我们可以这么解决:

router.js

import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter)
import page1  from './page1.vue';
import page2  from './page2.vue';
import user   from './user.vue'

const routes=[
    {path:'/page1',component:page1},
    {path:"/page2",component:page2},
    //可以配置重定向
    {path:'',redirect:"page1"}
    //或者重新写个路径为空的路由
    {path:"",component:page1}
]

const router=new VueRouter({
    routes
});

export default router

上面的两种解决方案都是可以解决的,配置重定向的意思就是当匹配到路径为空的时候,就会重定向到page1,执行page1的路由;或者我们也可以重新配置个路由,路径为空的时候router-view展示page1的页面;

用重定向和单独配置路由的区别:

  重定向实际上是当匹配到路径符合条件的时候去执行对应的路由,当然这个时候的url上面的地址显示的是对应的路由,页面也是对应的路由页面;

  重新配置路由是当匹配到路径符合条件的时候,router-view页面展示部分负责拿符合条件路由的页面来展示,实际上url是没有发生变化的;

那么还有些复杂情况,是基本路由实现不了的;我们来接着往下看

动态路由匹配:

  其实我们的生活中有很多这样的例子,不知道大家留意没有?比如一个网站或者后台管理系统中,在我们登录之后,是不是通常会有一个欢迎回来,XXX之类的提示语,这个我们就可以通过动态路由来实现这个效果;

首先在src目录下新建一个user.vue文件:

<template>
    <div>
        <h1>user</h1>
       //这里可以通过$route.params.name来获取路由的参数
        <p>欢迎回来,{
   {$route.params.name}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                msg: "我是page1组件"
            }
        }
    }
</script>

然后我们修改App.vue文件的代码:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div>
      <router-link to="/page1">Page1</router-link>
      <router-link to="/page2">Page2</router-link>
    </div>

//添加两个router-link标签
    <div>
      <router-link to="/user/xianyu">动态路由咸鱼</router-link>
      <router-link to="/user/mengxiang">动态路由梦想</router-link>
    </div>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

修改我们的router.js

import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter)
import page1  from './page1.vue';
import page2  from './page2.vue';
import user   from './user.vue'

const routes=[
    {path:'/page1',component:page1},
    {path:"/page2",component:page2},
    // {path:'',redirect:"page1"}
    {path:"",component:page1},
 //使用冒号标记,当匹配到的时候,参数值会被设置到this.$route.params中
    {path:"/user/:name",component:user}
    
]

const router=new VueRouter({
    routes
});

export default router

配置好了,不出意外是能正常运行的,我们来看一下效果:

动态路由匹配给我们提供了方便,使得我们通过配置一个路由来实现页面局部修改的效果,给用户造成一种多个页面的感觉,是不是很酷!!!

酷的同时也会给我们带来一些问题,因为使用路由参数时,从/user/xianyu导航到/user/mengxiang,原来的组件实例会被复用,两个路由都渲染同个组件,比起销毁再创建,显示复用显得效率更高,带来的的只管问题就是生命周期钩子函数不会再被调用,也就是不会再被触发;但是办法总比问题多,我们可以通过监听$route对象来实现;

修改user.vue的代码

<template>
    <div>
        <h1>user</h1>
        <p>欢迎回来,{
   {msg}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                // msg: "我是page1组件"
                msg:""
            }
        },
        watch:{
//to表示即将要进入的那个组件,from表示从哪个组件过来的
            $route(to,from){
                this.msg=to.params.name; 
                console.log(111);
            }
        }
    }
</script>

 效果图如下:

 

我们可以很明显的看到我们监听的$route对象被触发了,控制台也输出了;

下面我们来一起看一下嵌套路由:

  嵌套路由:

    很多时候我们的页面结构决定了我们可能需要嵌套路由,比如当我们进入主页之后有分类,然后当选择其中一个分类之后进入对应的详情,这个时候我们就可以用到嵌套路由;官方文档中给我们提供了一个children属性,这个属性是一个数组类型,里面实际放着一组路由;这个时候父子关系结构就出来了,所以children属性里面的是路由相对来说是children属性外部路由的子路由;

好记性不如烂代码,让我们通过代码来看一看:

  首先在我们的src目录下新建两个vue文件,分别是phone.vue和computer.vue

  phone.vue

<template>
    <div>
        <p>{
   {msg}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                msg: "嵌套手机组件"
            }
        }
    }
</script>

computer.vue

<template>
    <div>
        <p>{
   {msg}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                msg: "嵌套电脑组件"
            }
        }
    }
</script>

 然后我们再修改我们的App.vue文件:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div>
      <router-link to="/page1">Page1</router-link>
    </div>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

 

通过上面的App.vue文件我们可以看到,我们此时页面只有一个page1的标签了;

我们再来修改router.js

import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter)
import page1  from './page1.vue';
import page2  from './page2.vue';
import user   from './user.vue';
import phone  from './phone.vue';
import computer from './computer.vue'

const routes=[
    {
        path:'/page1',
        component:page1,
        children: [
            {
                path: "phone",
                component: phone
            },
            {
                path: "computer",
                component: computer
            },
        ]
    },
    // {path:"/page2",component:page2},
    // // {path:'',redirect:"page1"}
    // {path:"",component:page1},
    // {path:"/user/:name",component:user}
    
]

const router=new VueRouter({
    routes
});

export default router

为了大家看的直观点,其他路由全部注释了,页面只剩下/page1这一个路由了;

上面说到了,children属性其实就是一个子路由集合,数组结构里面放着子路由;

效果图如下:

 路由导航两种方式:

  标签导航:标签导航<router-link><router-link>是通过转义为<a></a>标签进行跳转,其中router-link标签中的to属性会被转义为a标签中的href属性;

//跳转到名为user路由,并传递参数userId
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

 编程式导航:我们可以通过this.$router.push()这个方法来实现编程式导航,当然也可以实现参数传递,这种编程式导航一般是用于按钮点击之后跳转

router.push({ name: 'user', params: { userId: 123 }})

 

这两者都会把路由导航到user/123路径

命名路由:

  有的时候,通过一个名称来标识一个路由显得更方便一些,所以官方为了方便我们偷懒,又给我们在路由中添加了一个name属性,命名这个属性之后我们访问这个属性就等于直接访问到路由;

  普通路由:

router.push({ path: '/user/:userId', params: { userId: 123 }})

命名路由:

router.push({ name: 'user', params: { userId: 123 }}) 

其实两者并没有什么区别,只是提供了两种方式来访问路由,可以通过路径来匹配也可以通过别名来匹配; 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mengdong_524/article/details/123402724

智能推荐

5个超厉害的资源搜索网站,每一款都可以让你的资源满满!_最全资源搜索引擎-程序员宅基地

文章浏览阅读1.6w次,点赞8次,收藏41次。生活中我们无时不刻不都要在网站搜索资源,但就是缺少一个趁手的资源搜索网站,如果有一个比较好的资源搜索网站可以帮助我们节省一大半时间!今天小编在这里为大家分享5款超厉害的资源搜索网站,每一款都可以让你的资源丰富精彩!网盘传奇一款最有效的网盘资源搜索网站你还在为找网站里面的资源而烦恼找不到什么合适的工具而烦恼吗?这款网站传奇网站汇聚了4853w个资源,并且它每一天都会持续更新资源;..._最全资源搜索引擎

Book类的设计(Java)_6-1 book类的设计java-程序员宅基地

文章浏览阅读4.5k次,点赞5次,收藏18次。阅读测试程序,设计一个Book类。函数接口定义:class Book{}该类有 四个私有属性 分别是 书籍名称、 价格、 作者、 出版年份,以及相应的set 与get方法;该类有一个含有四个参数的构造方法,这四个参数依次是 书籍名称、 价格、 作者、 出版年份 。裁判测试程序样例:import java.util.*;public class Main { public static void main(String[] args) { List <Book>_6-1 book类的设计java

基于微信小程序的校园导航小程序设计与实现_校园导航微信小程序系统的设计与实现-程序员宅基地

文章浏览阅读613次,点赞28次,收藏27次。相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低学校的运营人员成本,实现了校园导航的标准化、制度化、程序化的管理,有效地防止了校园导航的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正建筑速看等信息。课题主要采用微信小程序、SpringBoot架构技术,前端以小程序页面呈现给学生,结合后台java语言使页面更加完善,后台使用MySQL数据库进行数据存储。微信小程序主要包括学生信息、校园简介、建筑速看、系统信息等功能,从而实现智能化的管理方式,提高工作效率。

有状态和无状态登录

传统上用户登陆状态会以 Session 的形式保存在服务器上,而 Session ID 则保存在前端的 Cookie 中;而使用 JWT 以后,用户的认证信息将会以 Token 的形式保存在前端,服务器不需要保存任何的用户状态,这也就是为什么 JWT 被称为无状态登陆的原因,无状态登陆最大的优势就是完美支持分布式部署,可以使用一个 Token 发送给不同的服务器,而所有的服务器都会返回同样的结果。有状态和无状态最大的区别就是服务端会不会保存客户端的信息。

九大角度全方位对比Android、iOS开发_ios 开发角度-程序员宅基地

文章浏览阅读784次。发表于10小时前| 2674次阅读| 来源TechCrunch| 19 条评论| 作者Jon EvansiOSAndroid应用开发产品编程语言JavaObjective-C摘要:即便Android市场份额已经超过80%,对于开发者来说,使用哪一个平台做开发仍然很难选择。本文从开发环境、配置、UX设计、语言、API、网络、分享、碎片化、发布等九个方面把Android和iOS_ios 开发角度

搜索引擎的发展历史

搜索引擎的发展历史可以追溯到20世纪90年代初,随着互联网的快速发展和信息量的急剧增加,人们开始感受到了获取和管理信息的挑战。这些阶段展示了搜索引擎在技术和商业模式上的不断演进,以满足用户对信息获取的不断增长的需求。

随便推点

控制对象的特性_控制对象特性-程序员宅基地

文章浏览阅读990次。对象特性是指控制对象的输出参数和输入参数之间的相互作用规律。放大系数K描述控制对象特性的静态特性参数。它的意义是:输出量的变化量和输入量的变化量之比。时间常数T当输入量发生变化后,所引起输出量变化的快慢。(动态参数) ..._控制对象特性

FRP搭建内网穿透(亲测有效)_locyanfrp-程序员宅基地

文章浏览阅读5.7w次,点赞50次,收藏276次。FRP搭建内网穿透1.概述:frp可以通过有公网IP的的服务器将内网的主机暴露给互联网,从而实现通过外网能直接访问到内网主机;frp有服务端和客户端,服务端需要装在有公网ip的服务器上,客户端装在内网主机上。2.简单的图解:3.准备工作:1.一个域名(www.test.xyz)2.一台有公网IP的服务器(阿里云、腾讯云等都行)3.一台内网主机4.下载frp,选择适合的版本下载解压如下:我这里服务器端和客户端都放在了/usr/local/frp/目录下4.执行命令# 服务器端给执_locyanfrp

UVA 12534 - Binary Matrix 2 (网络流‘最小费用最大流’ZKW)_uva12534-程序员宅基地

文章浏览阅读687次。题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=93745#problem/A题意:给出r*c的01矩阵,可以翻转格子使得0表成1,1变成0,求出最小的步数使得每一行中1的个数相等,每一列中1的个数相等。思路:网络流。容量可以保证每一行和每一列的1的个数相等,费用可以算出最小步数。行向列建边,如果该格子是_uva12534

免费SSL证书_csdn alphassl免费申请-程序员宅基地

文章浏览阅读504次。1、Let's Encrypt 90天,支持泛域名2、Buypass:https://www.buypass.com/ssl/resources/go-ssl-technical-specification6个月,单域名3、AlwaysOnSLL:https://alwaysonssl.com/ 1年,单域名 可参考蜗牛(wn789)4、TrustAsia5、Alpha..._csdn alphassl免费申请

测试算法的性能(以选择排序为例)_算法性能测试-程序员宅基地

文章浏览阅读1.6k次。测试算法的性能 很多时候我们需要对算法的性能进行测试,最简单的方式是看算法在特定的数据集上的执行时间,简单的测试算法性能的函数实现见testSort()。【思想】:用clock_t计算某排序算法所需的时间,(endTime - startTime)/ CLOCKS_PER_SEC来表示执行了多少秒。【关于宏CLOCKS_PER_SEC】:以下摘自百度百科,“CLOCKS_PE_算法性能测试

Lane Detection_lanedetectionlite-程序员宅基地

文章浏览阅读1.2k次。fromhttps://towardsdatascience.com/finding-lane-lines-simple-pipeline-for-lane-detection-d02b62e7572bIdentifying lanes of the road is very common task that human driver performs. This is important ..._lanedetectionlite

推荐文章

热门文章

相关标签