后端人眼中的Vue(四)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

十、路由router

10.1、路由简介

说起路由你会想到啥

1570332749754

路由器那路由器是用来做什么的你有没有想过

  • 路由时决定数据包从来源到目的地的路径
  • 将输入端的数据转移到合映射表适的输出端
  • 路由中最重要的概念就是路由表路由表的本质就是一个映射表决定了数据包的指向

10.2 路由分类

10.2.1、后端路由

早期的网站开发整个HTML页面是由服务器来渲染的。服务器将渲染好的对应的HTML页面返回给客户端进行展示但是一个网站包含很多页面那服务器是怎么处理的呢

每个页面都有对应的网址也就是URLURL会发送给到服务器服务器会通过正则对该URL进行匹配最后交给Controller进行处理。Controller进行处理最终生成HTML或者数据然后返回给前端这其实就是服务器的一个IO操作这其实就是对后端对路由的解析。这种后端渲染的好处相对于发送ajax请求拿数据可以提高首屏渲染的性能也有利于SEO的优化。但是后端路由转发也是有缺点的

  1. 另一种情况是前端开发人员如果要开发页面, 需要通过PHP和Java等语言来编写页面代码。
  2. 而且通常情况下HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情

10.2.2、前端路由

10.2.2.1、前端路由简介

随着Ajax的出现有了前后端分离的开发模式后端只提供API来返回数据jsonxml前端通过Ajax获取数据并且可以通过JavaScript将数据渲染到页面中这样做最大的优点就是前后端责任的清晰, 后端专注于数据上, 前端专注于交互和可视化上也就是我们常说的解耦并且当移动端(iOS/Android)出现后, 后端不需要进行任何处理, 依然使用之前的一套API即可目前很多的网站依然采用这种模式开发。

在单页面应用阶段SPA最主要的特点就是在前后端分离的基础上加了一层前端路由也就是前端来维护一套路由规则。那么前端路由的核心是什么呢改变URL但是页面不进行整体的刷新。

10.2.2.2、前端路由规则

10.2.2.2.1、hash哈希路由

URL的hash也就是锚点(#), 本质上是改变window.locationhref属性我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新。

1570334725348

10.2.2.2.2、HTML5的history模式

history接口时HTML5新增的它有5种模式改变URL而不刷新页面。

history.pushState(data, title, url)

1570335079799

history.replaceState(data, title, url)

1570335225629

history.go(-1)返回上一页

history.back()等价于 history.go(-1)

history.forward()等价于 history.go(1)

10.3、Vue-router基本使用

通过使用Vue-router可以使得Vue开发变得更加灵活他可以根据前端请求对应的url在页面中展示不同的组件。

目前前端流行的三大框架都有自己的路由实现

  • Angular的ngRouter
  • React的ReactRouter
  • Vue的vue-router

10.3.1、认识vue-router

vue-router是Vue的官方路由插件它和Vue是深度集成的适合用于构建单页面应用 https://router.vuejs.org/zh/

vue-router是基于路由和组件的,路由用于设定访问路径, 将路径和组件映射起来。在vue-router的单页面应用中, 页面的路径的改变就是组件的切换让构建单页面应用更简单。

10.3.2、安装vue-router

vue-router是依赖于Vue.js所以vue-router的加载要在Vue.js的下面。可以去下载也可以通过在线引用的方式进行引用官方给了一个CDN地址https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js"></script>
</head>

<body>
    <div id='app'>

    </div>
</body>

</html>
<script>
    // 登录组件
    login = {
        template:'<h1>用户登录</h1>'
    }
    // 注册组件
    reg = {
        template:'<h1>用户注册</h1>'
    }

    // 创建路由规则对象
     const router = new VueRouter({
        // 配置路由规则
        routes: [ 
            // 当以login访问时访问对应login组件
            {path:'/login',component:login},
            {path:'/reg',component:reg},
        ]
    })

    new Vue({
        el: '#app',
        data: {
        },
        methods: {
        },
        router, // 注册路由根据ES6语法变量名等于参数名可以直接省略只写一遍
    }); 
</script>

我们会发现他报错了。

image-20230104101650183

原因可能是可能是使用 vue-router 版本过高。这是未修改前的。

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js"></script>

修改为这样即可不会报错了。

    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <!-- 低版本也可以使用 -->
    <script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>

image-20230104101823875

我们此时会发现地址栏有点奇怪的变化有一个#

image-20230104102034504

这个#实际上叫做哈希路由。

编写好注册好组件以后应该怎么显示呢我们需要使用显示路由组件的标签。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <!-- 低版本也可以使用 -->
    <!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>

</head>

<body>
    <div id='app'>
        <!-- 显示路由组件标签 -->
        <router-view ></router-view>
    </div>
</body>

</html>
<script>
    // 登录组件
    login = {
        template: '<h1>用户登录</h1>'
    }
    // 注册组件
    reg = {
        template: '<h1>用户注册</h1>'
    }

    // 创建路由规则对象
    const router = new VueRouter({
        // 配置路由规则
        routes: [
            // 当以login访问时访问对应login组件
            { path: '/login', component: login },
            { path: '/reg', component: reg },
        ]
    })

    new Vue({
        el: '#app',
        data: {
        },
        methods: {
        },
        router, // 注册路由根据ES6语法变量名等于参数名可以直接省略只写一遍
    }); 
</script>

加了显示路由组件的标签后刷新还是没有任何反应该怎么访问呢还记得我们写过的路由规则吗我们要加上对应的名字才可以访问比如说我访问登录组件就加一个/login

image-20230104102300947

改为/reg后就会切换到注册组件。

image-20230104102340583

如果我们胡乱写一个没有匹配对应的路由那么就啥也不显示。

image-20230104102515552

这样还是很不方便我们作为开发者知道切换/后面的名字就可以切换组件但是用户不一定知道哇所以就可以给用户做一个菜单用户直接点击即可切换。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <!-- 低版本也可以使用 -->
    <!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>

</head>

<body>
    <div id='app'>
        <a href="">登录</a>
        <a href="">注册</a>
        <!-- 显示路由组件标签 -->
        <router-view ></router-view>
    </div>
</body>

</html>
<script>
    // 登录组件
    login = {
        template: '<h1>用户登录</h1>'
    }
    // 注册组件
    reg = {
        template: '<h1>用户注册</h1>'
    }

    // 创建路由规则对象
    const router = new VueRouter({
        // 配置路由规则
        routes: [
            // 当以login访问时访问对应login组件
            { path: '/login', component: login },
            { path: '/reg', component: reg },
        ]
    })

    new Vue({
        el: '#app',
        data: {
        },
        methods: {
        },
        router, // 注册路由根据ES6语法变量名等于参数名可以直接省略只写一遍
    }); 
</script>

a标签里面的href属性怎么写呢不可以写绝对路径这样项目上线的时候这里全部都要改一点也不灵活。我们可以使用#/login的方式用#告诉Vue我这是一个路由的切换。#后面跟上路由名字。不加#Vue会把他当成一个绝对地址而不是路由切换。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <!-- 低版本也可以使用 -->
    <!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>

</head>

<body>
    <div id='app'>
        <a href="#/login">登录</a>
        <a href="#/reg">注册</a>
        <!-- 显示路由组件标签 -->
        <router-view ></router-view>
    </div>
</body>

</html>
<script>
    // 登录组件
    login = {
        template: '<h1>用户登录</h1>'
    }
    // 注册组件
    reg = {
        template: '<h1>用户注册</h1>'
    }

    // 创建路由规则对象
    const router = new VueRouter({
        // 配置路由规则
        routes: [
            // 当以login访问时访问对应login组件
            { path: '/login', component: login },
            { path: '/reg', component: reg },
        ]
    })

    new Vue({
        el: '#app',
        data: {
        },
        methods: {
        },
        router, // 注册路由根据ES6语法变量名等于参数名可以直接省略只写一遍
    }); 
</script>

在这里插入图片描述

10.3.3、切换路由

10.3.3.1、标签切换

每次都打#还挺麻烦的所以Vue给了切换路由的标签router-link>当我们写了一个router-link标签时发现啥也不显示这是因为我们还要写to这个属性表明切换到哪个组件。

我们可以看到他的底层也是a标签。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-drhXmOKX-1673761553967)(https://gitee.com/ljpxx/study-note/raw/master/202301151341528.png)]

to属性里面写/组件名称省去写#这是最简单的写法。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <!-- 低版本也可以使用 -->
    <!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>

</head>

<body>
    <div id='app'>
        <a href="#/login">登录</a>
        <a href="#/reg">注册</a>
        <!-- 显示路由组件标签 -->
        <router-view ></router-view>
        <router-link to="/login">我是路由切换用户登录</router-link>
    </div>
</body>

</html>
<script>
    // 登录组件
    login = {
        template: '<h1>用户登录</h1>'
    }
    // 注册组件
    reg = {
        template: '<h1>用户注册</h1>'
    }
    // 404组件
    noFound = {
        template: '<h1>404页面</h1>'
    }

    // 创建路由规则对象
    const router = new VueRouter({
        // 配置路由规则
        routes: [
            // 当以login访问时访问对应login组件
            { path: '/login', component: login },
            { path: '/reg', component: reg },
            // 重定向一开始就跳转到login组件中
            {path:'/',redirect: '/login'},
            {path:'*',component:noFound}
        ]
    })

    new Vue({
        el: '#app',
        data: {
        },
        methods: {
        },
        router, // 注册路由根据ES6语法变量名等于参数名可以直接省略只写一遍
    }); 
</script>

他的完整写法是在to里面写一个路由规则对象。类似这样:to=path{'/login'}

我们不仅可以通过路径切换路由还可以通过名称来切换路由通过路由对象名称切换路由显示不同的组件想根据名称切换路由只能使用router-link

首先我们在注册组件的时候要先指定一个名称即name属性。

// 创建路由规则对象
    const router = new VueRouter({
        // 配置路由规则
        routes: [
            // 当以login访问时访问对应login组件
            { path: '/login', component: login,name:'Login' },
            { path: '/reg', component: reg },
            // 重定向一开始就跳转到login组件中
            {path:'/',redirect: '/reg'},
            {path:'*',component:noFound}
        ]
    })

在使用名称切换路由时用name这个属性来切换。推荐使用这种方式来切换路由使用命名切换路由更加解耦合。

 <router-link :to="{name:'Login'}">我是路由切换用户登录</router-link>

10.3.3.2、Js切换路由

我们还可以通过Js代码中切换路由。this中有两个属性

  1. this.$route表示当前路由对象。
  2. this.$router表示路由管理器对象VueRouter。

使用Js代码用路由器管理对象去切换当前路由对象即可切换路由。

this.$router.push({path:'/login'}) // 根据路径切换路由
this.$router.push('/login') // 根据路径切换路由简化写法
this.$router.push({name:'Login'}) // 根据名字切换路由这是我们推荐的

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>vue系列课程</title>
</head>
<body>
    <div id="app">
        <h1>{{msg}}</h1>


        <!--切换路由: 1.通过标签直接切换   2.在js代码中切换-->
        <router-link :to="{name:'Login'}">用户登录</router-link>
        <router-link :to="{name:'Register'}">用户注册</router-link>


        <!--2.在js代码中切换路由-->
        <button @click="login">用户登录</button>
        <button @click="register">用户注册</button>

        <!--展示路由组件标签-->
        <router-view/>
    </div>
</body>
</html>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 低版本也可以使用 -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
<script>

    //login
    const login =  {
        template:`<div><h4>用户登录</h4></div>`
    };
    //register
    const register =  {
        template:`<div><h4>用户注册</h4></div>`
    };

    //1.创建路由规则对象
    const router = new VueRouter({
        routes:[
            //name:这个属性代表路由对象名称  用来给路由对象一个唯一名称标识
            {path:'/login',component:login,name:'Login'},
            {path:'/register',component:register,name:'Register'},
        ]
    });


    //解决同一个路由多次切换报错的问题
    const originalPush = VueRouter.prototype.push;
    VueRouter.prototype.push = function push(location) {
        return originalPush.call(this, location).catch(err => err)
    };

    const app = new Vue({
        el: "#app",
        data: {
            msg:"vue router 基本使用之在js代码中切换路由"
        },
        methods:{
            login(){
                //发送axios请求完成登录 响应回来之后切换路由到主页
                //this.$route object 当前路由对象   this.$router vueRouter  代表路由管理器对象
                //console.log(this.$route.name);
                //this.$router.push('/login');//切换路由
                //this.$router.push({path:'/login'});
                //在vuerouter 中多次切换相同路由出现错误 1.每次切换之前手动判断   2.加入官方一段配置解决错误问题
                // if(this.$route.name!='Login'){
                //     this.$router.push({name:'Login'});//使用名称切换
                // }
                this.$router.push({name:'Login'});//使用名称切换
            },
            register(){
                //console.log(this.$route.name);
                // if(this.$route.name!='Register') {
                //     this.$router.push({name: 'Register'});//使用名称切换
                // }
                this.$router.push({name: 'Register'});//使用名称切换
            }
        },
        router,//注册路由对象
    });
</script>

10.3.2.3、切换路由之传递参数

他支持两种方式的传参

  1. queryString方式即url拼接参数通过this.$route.query.key来直接获取。
  2. restful风格传参即路径传参。

在使用queryString方式传递参数的时候参数都在query里面。

image-20230105151201606

如果通过<router-link>的方式传递多个参数可以这样写。

        <router-link :to="{path:'/login?name=xiaolin&password=123456'">用户登录</router-link>

检验一下是否可以传递参数。

            console.log(this.$route.query.name+"=====");//获取当前路由对象
            console.log(this.$route.query.password+"=====");//获取当前路由对象

image-20230105152223515

在通过queryString方式传递参数的时候Vue底层本质上是把他封装到query对象里面去我们也可以直接把他封装到query对象里面。

        <router-link :to="{name:'Login',query:{name:'xiaoxiaolin',password:123456}}">用户登录</router-link>

在通过restful传参的时候我们在定义路由的时候需要修改一下你path使用:id方式告诉Vue这是我传递的参数参数名为id。

{path:'/register/:id'}

如果有多个参数的时候可以直接接着往下面拼接。

{path:'/register/:id/:name'}

表示这是传递了两个参数一个id一个name。我们可以看到参数都在params力买买而不是在path里面。

image-20230105151113511

使用restful方式传参的时候也可以通过<router-link>标签的方式进行传参但是不可以直接在url路径后拼接参数因为restful方式传参的时候参数会被封装到params里面去所以我们可以直接把参数封装到params里面去。

<router-link :to="{path:'/register/22/xiaolin'}">用户注册</router-link>
<router-link :to="{name:'Register',params:{id:233,name:'xiaolin'}}">用户注册</router-link>
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: vue