• 图书信息管理系统(二)


    本文是我在学习过程中记录学习的点点滴滴,目的是为了学完之后巩固一下顺便也和大家分享一下,日后忘记了也可以方便快速的复习。


    前言

    今天学习的主要是关于登录页面的设计和逻辑实现的理解和应用


    一、登陆界面设计

    1.1、新建登录组件index.vue

    views 文件夹(放路由组件的)下新建 login 文件夹,然后新建登录组件 index.vue(这样的好处是导入组件时只要到文件夹位置即可,后面 index.vue 名称不用写,因为默认就会找 index.vue)

    <template>
    <div>
    登录页面
    </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.2、配置路由index.js

    打开 router/index.js 文件

    import Vue from "vue";
    import VueRouter from "vue-router";
    //导入登录组件,后面的 index.vue 可以不写,因为默认就会找
    index.vue,这就是为什么取名为 index.vue 的好处。
    import Login from "../views/login/index.vue" Vue.use(VueRouter);
    const routes = [
    {//配置登录路由
    
    path: "/login", name: "login", component: Login
    }, ];
    const router = new VueRouter({
    mode: "history", base: process.env.BASE_URL, routes
    });
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.3、清理下根组件 App.vue

    <template>
    <div id="app">
    //<!-- 显示路由组件位置 -->
    <router-view />
    </div>
    </template>
    <style lang="scss">
    body {
    font: "微软雅黑";
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.4、测试

    测试下,看到一个空白页面,因为当前显示的是 App.vue 组件,而该组件中没有内容,然后手动地址栏后输入/login 路由,显示登录页面,如下:
    在这里插入图片描述

    二、使用 element 完善系统登录界面设计

    2.1、登录界面 Index.vue 表单

    直接根据 Element UI 中的表单进行修改
    【参考 Form 表单——典型表单即可】。完善后的代码如下:

    <template>
    <div id="login-container">
    <el-form ref="form" :model="form" label-width="60px" class="login-form">
    <h2 class="login-title">小豆子图书信息管理系统</h2>
    <el-form-item label="账号">
    <el-input v-model="form.username" placeholder="请输入账号"></el-input>
    </el-form-item>
    <el-form-item label="密码">
    <el-input v-model="form.password" type="password" placeholder="请输入密码"></el-input>
    </el-form-item>
    <el-form-item>
    <el-button type="primary" @click="onSubmit">登录</el-button>
    </el-form-item>
    </el-form>
    </div>
    </template>
    <script>
    export default {
    data() {
    return {
    form: {
    username: '', password: '', }
    }
    },methods: {
    onSubmit() {
    console.log('submit!');
    }
    }
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    效果如下:在这里插入图片描述

    2.2、登陆界面index.vue表单美化

    <style scoped>
    #login-container {
      /* 让这个div100%布满屏幕 */
      position: absolute;
      width: 100%;
      height: 100%;
      background-image: url("../../assets/login-bg.jpg");
      background-size: cover;
    }
    .login-form {
      width: 350px;
      background-color: rgb(191, 208, 223);
      /* margin: 160px auto; */
      padding: 15px;
      border-radius: 20px;
      height: 250px;
      /* 让它真正的居中 */
      left: 50%;
      top: 50%;
      margin-left: -175px;
      margin-top: -125px;
      position: absolute;
    }
    .login-title {
      color: rgb(9, 10, 10);
      text-align: center;
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    效果如下:在这里插入图片描述

    2.3、App.vue的美化

    <style lang="scss">
    body {
      font: "微软雅黑";
      // 解决主页上下左右多出一点点出现滚动条
      margin: 0px auto;
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、使用 element 完善系统登录界面设计

    3.1、登录表单验证功能

    Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。

    index.vue 改变以下黄色底纹处。(增加以下 4 处黄色底纹代码)
    (1)
    <el-form :rules=“rules” ref=“form” :model=“form” labelwidth=“60px” class=“login-form”>
    (2)
    <el-form-item label=“账号” prop=“username”>
    <el-input v-model=“form.username” placeholder=“请输入账号”></el-input>
    </el-form-item>
    (3)
    <el-form-item label=“密码” prop=“password”>
    <el-input v-model=“form.password” type=“password” p
    laceholder=“请输入密码”></el-input>
    </el-form-item>
    (4)
    data() {
    return {
    form: {
    username: ‘’, password: ‘’, },
    rules: {
    username: [
    {required: true, message: ‘请输入账号’, trigger: ‘blur’},
    ],
    password: [
    {required: true, message: ‘请输入密码’, trigger: ‘blur’},
    {min: 6, max: 32, message: ‘密码长度在 6 到 32 个字符’,
    trigger: [‘blur’, ‘change’]}
    ]
    }

    }
    },

    <template>
      <div id="login-container">
        <el-form
          :ref="form"
          :rules="rules"
          :model="form"
          label-width="60px"
          class="login-form"
        >
          <h2 class="login-title">小豆子图书管理系统</h2>
          <el-form-item label="账号" prop="username">
            <el-input v-model="form.username" placeholder="请输入账号"></el-input>
          </el-form-item>
          <el-form-item label="密码" prop="password">
            <el-input
              v-model="form.password"
              type="password"
              placeholder="请输入密码"
            ></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitForm(form)">登录</el-button>
          </el-form-item>
        </el-form>
      </div>
    </template>
    <script>
    //import loginAPI from '@/API/login' 
    //login.js 中 js 不用写,不过这种导入方式导入的是默认对象,而在 login.js 导出的是普通函数对象,所以换下面的按需导入
    import { login, getUserInfo } from "@/api/login";
    export default {
      data() {
        return {
          form: {
            username: "",
            password: "",
          },
          //定义账号密码的输入规则
          rules: {
            username: [{ required: true, message: "请输入账号", trigger: "blur" }],
            password: [
              { required: true, message: "请输入密码", trigger: "blur" },
              {
                min: 6,
                max: 23,
                message: "长度在6~23个字符",
                trigger: ["blur", "change"],
              },
            ],
          },
        };
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    3.2、登录功能实现

    目前不管账号和密码如何输入,都会触发 onSubmit 方法提交数据的,通过控制台可以看到输出了“submit”。
    实际需要的是当表单全部校验通过才能去提交数据到后台去。与后台存在的账号进行比对。

    (1)原先 onSubmit 方法替换为下面的submitForm方法代码(也是element 官网复制——自定义校验规则)

    methods: {
    submitForm(formName) {
    this.$refs[formName].validate(valid => {
    if (valid) { //valid 为 true 表示所有表单校验通过
    alert("submit!");
    } else {
    console.log("error submit!!");
    return false;
    }
    });
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    (2)对应提交方法原来是 onSubmit()改为 submitForm。同时根据 submitForm 方法参数可知,需要传入一个要提交的表单。也就是<el-from 表签中 ref 属性值在这里插入图片描述

    运行测试,发现汇报如下错误:
    TypeError: this.$refs[formName] is undefined。
    如何解决呢?这是因为版本问题,需要在 ref="form"前面加:再次运行测试——ok。

    四、使用 Easymock 为登录验证创建模拟接口

    因为这个网站是不使用服务器的,所以就使用Easymock模拟数据库来创建数据。Easy mock相当于一个虚拟的数据库,它可以虚构出你想要的任何数据,并且十分逼真,名字真的很像名字,地址真的很像地址!用了成龙大哥都说好!!!

    接下来我们要把数据提交到后台去,后台要做 2 件事情:第一,去查找是否存在对应的登录用户与密码;第二,返回响应(是否成功登陆)给客户端。

    4.1、首先修改下我们服务接口基础地址

    在这里插入图片描述复制这段代码串,打开.env.development 文件修改接口服务地址(就是把请求的目标地址改成easy mock上,这样请求的数据就是easy mock的数据):
    # 接口服务地址, 就是 vue.config.js 中 target 值
    VUE_APP_SERVICE_URL = ‘https://www.easy-mock.com/mock/5e78be09048b0c4cff679b80’

    4.2、创建服务接口(配置 mock.js)

    假设后台只要请求成功,状态码统一规定为 200

    (1)创建一个登录认证的接口(失败的不写,即用户名或密码不对)
    请求 URL: /user/login
    请求方式: post
    描述:登陆认证
    接口响应的信息如下(这里假设只有成功情况,失败情况的信息不写)

    { "code": 200, // 状态码
    "flag": true, 
    "message": '验证成功',
    "data":
    { "token": "admin" }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    (2)添加响应用户信息模拟接口
    请求 URL: /user/info/{token} //{token}是一个占位符,后续
    请求该接口时传入 token,注意标点符号均为英文的
    请求方式: get
    描述:响应用户信息

    { "code": 200,
     "flag": true,
      "message": '成功获取用户信息',
    "data": //生成数据的规则
    { "id|1-1000": 1,
     "name": "@cname",//cname是中文名字,name是英文名字
     "roles": ["manager"]}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    在这里插入图片描述调用接口出现接收到上面信息,就表示成功获取到用户信息,就可以登录到主页面了。

    五、登录业务逻辑实现

    总结:
    这里主要是通过点击登录按钮来触发submitForm(formName)方法。
    我们上面在easy mock里定义了两个接口,首先我们在login.js里引入我们自己封装的myaxios.js来发送异步请求,login.js里定义了两个方法分别来发送请求去请求easy mock里的两个接口获取数据,所以这里是按需导出,分别导出两个方法。
    然后,再在index.vue登陆界面来通过登录按钮来调用submitForm(formName)方法,这个formName是传过来的参数form,这个form就是这整个表单(属性ref=form)。this.$refs[formName].validate((valid) => {}方法里面是获取ref=form的这个表单的校验结果。
    如果校验成功则调用login接口并传入参数,然后login接口就会从easy mock中返回数据,如果成功获取数据,认证成功则获取data里面的token令牌。
    再然后调用另一个接口getUserInfo(resp.data.token)并传入参数token,如果调用getUserInfo接口成功获取到返回的数据,那么就进一步获取用户的信息并把它存储到浏览器本地内存中,最后再跳转到首页面。

    5.1、创建 api 接口文件 login.js

    在 src/api/创建 login.js,用于发送 ajax 请求调用 API 接口。(回顾 test.js 如何创建)

    import myaxios from '@/utils/myaxios'
    //发送 ajax 请求,传入账户、密码,用于验证用户是否有资格
    export function login(username,password){
        //返回这个promise对象以供后续操作.then.catch
        return myaxios({
            url:'/user/login',//最前面的/不要少的
            method:'post',//url 和 method 两个属性值与前面创建接口时保持一致
            data:{//发送请求,并带数据过去
                username, //username:username
                password
            }
        })
    }
    //发送 ajax 请求,传入 token,用于获取用户信息
    export function getUserInfo(token){
        return myaxios({
            url:`user/info/${token}`, //由于这里需要拼接占位符,所以用``
            method:'get'
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    上面 myaxios 是发送异步请求,返回值是一个 promise 格式的异步对象,通过 return 返回得到就是那个 promise 异步对象,后续就可以通过 promise 异步对象的 then 执行回调

    5.2、使用 login.js 发送异步请求

    登录组件 index.vue 中导入 login.js,从而使用发送异步请求
    import { login, getUserInfo } from “@/API/login”;
    使用 login, getUserInfo 两个函数发送异步请求

    <script>
    //import loginAPI from '@/API/login' 
    //login.js 中 js 不用写,不过这种导入方式导入的是默认对象,而在 login.js 导出的是普通函数对象,所以换下面的按需导入
    import { login, getUserInfo } from "@/api/login";
    export default {
      data() {
        return {
          form: {
            username: "",
            password: "",
          },
          //定义账号密码的输入规则
          rules: {
            username: [{ required: true, message: "请输入账号", trigger: "blur" }],
            password: [
              { required: true, message: "请输入密码", trigger: "blur" },
              {
                min: 6,
                max: 23,
                message: "长度在6~23个字符",
                trigger: ["blur", "change"],
              },
            ],
          },
        };
      },
      methods: {
        submitForm(formName) {
          // valid是指表单验证结果(就是输入是否符合规则)
          this.$refs[formName].validate((valid) => {
            //valid 为 true 表示所有表单校验通过,符合规则
            if (valid) {
              //校验成功,调用login接口
              login(this.form.username, this.form.password).then((response) => {
                console.log(response.data);
                const resp = response.data;
                if (resp.flag) {
                  //认证通过,获取token令牌,调用另一个接口
                  getUserInfo(resp.data.token).then((response) => {
                    console.log(response.data);
                    const respUser = response.data;
                    if (respUser.flag) {
                      //获取用户信息
                      //存储信息到浏览器本地
                      localStorage.setItem("llf-manager-user",JSON.stringify(respUser.data));
                      localStorage.setItem("llf-manager-token", resp.data.token);
                      this.$router.push("./");//获取到后跳转到主页面
                    } else {
                      //获取用户信息失败
                      this.$message({
                        message: respUser.message,
                        type: "warning",
                      });
                    }
                  });
                } else {
                  //认证失败
                  this.$message({
                    message: resp.message,
                    type: "warning",
                  });
                }
              });
            } else {
              //校验失败
              console.log("error submit!!");
              return false;
            }
          });
        },
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    💕 原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 \textcolor{blue}{原创不易,还希望各位大佬支持一下}

    👍 点 赞 , 你 的 认 可 是 我 创 作 的 动 力 ! \textcolor{orange}{点赞,你的认可是我创作的动力!}

    收 藏 , 你 的 青 睐 是 我 努 力 的 方 向 ! \textcolor{red}{收藏,你的青睐是我努力的方向!}

    🥕 评 论 , 你 的 意 见 是 我 进 步 的 财 富 ! \textcolor{green}{评论,你的意见是我进步的财富!}

  • 相关阅读:
    场景交互与场景漫游-路径漫游(7)
    Selenium基础 — 拓展:使用浏览器加载项配置实现用户免登陆
    解锁C语言结构体的力量(进阶)
    Ubuntu18.04安装mysql8.0,亲测有效(内附安装时会遇到的一些情况)
    如何创建Facebook的WhatsApp广告
    力扣刷题day36|416分割等和子集
    小程序web-view无法打开该页面的解决方法
    【洛谷P1119】灾后重建【Floyed最短路】
    git clone:SSL: no alternative certificate subject name matches target host name
    14.webpack ----Vue源码的打包
  • 原文地址:https://blog.csdn.net/qq_46152664/article/details/125337760