测试平台开发(二) 高逼格登录页面

测试平台开发(二) 高逼格登录页面


<span>测试平台开发(二) 高逼格登录页面</span>

怎么样?哎哟,不错哦。本文就带大家一起用 Vue + Element-UI 把这个不错的登录页面开发出来。

项目结构分析

在使用 Vue-CLI 创建 2.x 的脚手架项目后,会生成如下目录文件:


<span>测试平台开发(二) 高逼格登录页面</span>

针对这个目录文件我写了一个脑图进行说明:

(文字稍微有点多,赶时间的同学看红色部分就可以了


<span>测试平台开发(二) 高逼格登录页面</span>

红色最多的是 src 文件夹,写的代码大部分都是放在这个文件夹下面。

重要提示,一下就刷到这里,只看文字不看图的同学,还是把图多看几秒哦,看不清楚,可以放大看,哈哈哈。

程序执行流程

按照我自己对 Vue 的理解,画了一张几个主要文件之间程序调用执行的流程图:

(水平有限,有错误请指正)


<span>测试平台开发(二) 高逼格登录页面</span>

图中简单描绘了 index.html、main.js、App.vue、store\index.js、router\index.js、views\login\index.vue 这几个文件之间的调用逻辑。暂时没有用到 components,因为登录界面不涉及到功能组件,只是个页面,代码放在 views 文件夹下即可。

哈哈我又来提醒了,只看文字不看图的同学,多看几眼,看不清楚,请放大!

源码

本文接下来会对这些文件逐个进行代码解析,为了不让文章变得冗长,只贴部分代码,完整代码请到 GitHub 获取:

https://github.com/dongfanger/sprint-frontend

如果想把这个项目复原出来,只看我写的文章是不够的,git clone顺手点个 star,学习效果更好哦。

index.html

index.html 是项目中唯一的 html 文件

因为 Vue 实现的是单页面应用。单页面应用,简单理解就是只有一个页面,其他页面都是通过组件的形式挂载到这个页面上的,这样页面切换就会更快速,如桌面应用一般丝滑顺畅。

其他页面的挂载点其实就是一个 div,其他页面都在放在这个 div 里面的:

    <div id="app"></div>

views\login\index.vue

本项目是基于 Element-UI 的,需要使用 npm 安装一下

npm i element-ui -S

.vue 文件是 Vue 框架的代码文件,分为3个部分

<template>
    html 模板
</template>

<script>
	javascript 脚本
</script>

<style lang="scss" scoped>
	css 样式
</style>

为了文章简洁,本文不展示 css 样式的代码。

template html 模板代码如下,实现了用户名、密码、登录等输入框和按钮:

<template>
  <div class="loginbody" :style="`background-image: url(${appInfo.backgroundImageUrl})`">
    <div class="login-box">
      <div class="login-title">
        <img class="login-logo" :src="appInfo.loginLogoUrl" alt="logo" />
        <p>{{ appInfo.title }}</p>
      </div>

      <div class="login-info">
        <el-form ref="form" class="form-box" :model="form" :rules="formRules">
          <el-form-item :label="'用户名'" prop="username">
            <el-input v-model="form.username" placeholder="请输入用户名" @keyup.enter.native="login" ref="username-input">
            </el-input>
          </el-form-item>
          <el-form-item :label="'密码'" prop="password">
            <el-input
                    v-model="form.password"
                    placeholder="请输入密码"
                    type="password"
                    show-password
                    @keyup.enter.native="login"
            ></el-input>
          </el-form-item>
          <el-form-item>
            <div class="clear">
              <el-checkbox
                      v-model="form.rememberMe"
                      :value="true"
                      :label="'记住密码'"
                      name="type"
                      class="remember-checkbox"
              ></el-checkbox>
              <span class="self-right forgetPwd" @click="forgetPwd">忘记密码?</span>
            </div>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="login" class="login-btn" :loading="isLoging">
              {{ "登录" }}
            </el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

其中页面背景图、logo 图、页面标题是通过 Vuex 来存取的。

Vuex 是 Vue 的状态管理工具。Vue 组件之间数据传递一般是通过 export 和 import 的方式,但是对于全局数据,这种方式很难管理和维护。Vuex 作为中间媒介,帮助组件之间更好的传递数据。

javascript 脚本代码如下,给 template 模板填充数据,定义元素行为:

<script>
  import { mapGetters } from "vuex";
  export default {
    data() {
      return {
        form: {
          username: "",
          password: "",
          rememberMe: true
        },
        formRules: {
          username: [
            { required: true, message: "请输入用户名", trigger: "blur" },
            {
              trigger: "blur",
            },
          ],
          password: [{ required: true, message: "请输入密码", trigger: "blur" }],
        },
        isLoging: false,
      };
    },
    created() {
    },
    mounted() {
      let autofocusElement = this.$refs["username-input"];
      if (autofocusElement) {
        autofocusElement.focus();
      }
    },
    methods: {
      login() {
      },
      forgetPwd() {
        this.$alert("请联系管理员!", "提示", {
          confirmButtonText: "确定",
          callback: action => {
            this.$message({
              type: "info",
              message: `action: ${action}`,
            });
          },
        });
      },
    },
    computed: {
      ...mapGetters(["appInfo"]),
    },
  };
</script>

其中最后几行的 appInfo 就是定义的全局变量,使用 Vuex 来传递数据。

store\index.js

appInfo 的实现代码放在 store\index.js 文件中:

import Vue from 'vue'
import Vuex from 'vuex'

const navBarLogoUrl = require("@/assets/image/logo.png");
const loginLogoUrl = require("@/assets/image/logo@2x.png");
const backgroundImageUrl = require("@/assets/image/login-bg.png");
const favicon = require("@/assets/image/favicon.png");

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    appInfo: null,
  },
  getters: {
    appInfo: state => {
      if (state.appInfo) {
        return state.appInfo;
      }
      let localAppInfo = localStorage.getItem("AppInfo");
      if (localAppInfo) {
        return JSON.parse(localAppInfo);
      }
      return {
        dsp: "这是公众号“测试老树”开发的测试平台。",
        navBarLogoUrl,
        loginLogoUrl,
        backgroundImageUrl,
        faviconUrl: favicon,
        title: "测试平台",
      };
    },
  },
  mutations: {
    commitAppInfo(state, appInfo) {
      state.appInfo = appInfo;
    },
  },
  actions: {
    setAppInfo({ commit }, appInfo) {
      let info = {
        dsp: appInfo.dsp,
        title: appInfo.title || "测试平台",
        navBarLogoUrl: appInfo.navBarLogoUrl || navBarLogoUrl,
        loginLogoUrl: appInfo.loginLogoUrl || loginLogoUrl,
        backgroundImageUrl: appInfo.backgroundImageUrl || backgroundImageUrl,
        faviconUrl: appInfo.faviconUrl || favicon,
      };

      commit("commitAppInfo", info);
      localStorage.setItem("AppInfo", JSON.stringify(info));
      let { faviconUrl, title } = info;

      let iconElement = document.querySelector("#t-icon");
      iconElement.href = faviconUrl;

      document.title = title;
    },
  },
  modules: {},
});

App.vue

App.vue 是根组件,适合做一些初始化工作。

从“程序执行流程”小节的逻辑图中可以看到,数据存储的操作就是在 App.vue 调用的,代码如下:

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
  import { mapActions } from "vuex";
  export default {
    name: "App",
    data() {
      return {};
    },
    created() {
    },
    methods: {
      ...mapActions(["setAppInfo"]),
    },
  };
</script>

methods 调用了 setAppInfo 方法,给 appInfo 赋值。

router\index.js

到这里,登录页面的代码就已经撸完了。是吗?是的!

但是还无法访问,因为还没有給它配置路由,浏览器还不知道怎么才能跳转到这个登录页面。

路由就是访问路径,让浏览器知道输入一个 url 该把哪个页面展示给你看。在以前,页面跳转路由都是放到后端来做的,前端请求后端,后端把渲染好的 html 返回给前端。现在时代不同了,前端直接控制了路由,前后端传递的数据变少了,访问体验也更佳。比如以前地址栏 URL 跳转可能会白屏,现在不会了。

路由配置代码是放在 router\index.js 文件中的,默认 / 展示 Home 页面,访问 /login 展示 login 页面:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import login from "../views/login"

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    meta: {
      requireAuth: true,
    },
  },
  {
    path: "/login",
    meta: {
      title: "测试平台登录",
    },
    name: "login",
    component: login,
  },
]

const router = new VueRouter({
  routes
})

但是首页不能直接就给别人看呀,得先登录!所以需要编写一个拦截器,必须登录后,才可以访问首页,否则跳转到登录页面:

router.beforeEach((to, from, next) => {
  if (to.matched.some(auth => auth.meta.requireAuth)) {
    let token = localStorage.getItem("token");
    if (token) {
      next();
    } else {
      next({
        path: "/login",
      });
    }
  } else {
    next();
  }
});

main.js

main.js 是程序执行入口,以上所有代码都需要在 main.js 中声明一下:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Element from "element-ui"
import "./assets/style/global.scss";

Vue.config.productionTip = false

Vue.use(Element)
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

vue.config.js

vue.config.js 是 Vue 项目配置文件。比如 index.html 中,页面 title 是通过 <title><%= htmlWebpackPlugin.options.title %></title> 来定义的,可以在配置文件中添加自定义,为 “sprint”:

const path = require("path");

function resolve(dir) {
  return path.join(__dirname, dir);
}
module.exports = {
  publicPath: process.env.NODE_ENV === "development" ? "./" : "/frontend/",
  chainWebpack: config => {
    config.plugin("html").tap(args => {
      args[0].title = "sprint";
      return args;
    });
  },
};

简要回顾

本文首先展示了登录页面的效果,接着介绍了 Vue-CLI 初始化之后的项目结构,并对程序执行逻辑进行了分析,梳理出来了主要几个文件的调用流程,最后分别对各文件的代码进行了分析。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/2665.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • js中数组求和_多个数组对应项求和

    js中数组求和_多个数组对应项求和js数组求和的5种方法题目描述计算给定数组arr中所有元素的总和输入描述:数组中的元素均为Number类型输入例子:sum([1,2,3,4])输出例子:101、不考虑算法复杂度,用递归做:functionsum(arr){varlen=arr.length;if(len==0){return0;}elseif(len==1){returnarr[0

  • MySQL数据库管理常用命令

    MySQL数据库管理常用命令

  • 宠物社区小程序_宠物论坛哪个好

    宠物社区小程序_宠物论坛哪个好微信小程序宠物论坛6个人主页页面JS部分constdb=wx.cloud.database()Page({data:{openid:””,nickname:””,heads:””},onLoad:function(options){constopenid=options.idthis.setData({openid:openid})console.log(this.data.openid)d

  • Lotus Notes视图索引的机制

    Lotus Notes视图索引的机制
    内容提要:
    本文对视图的索引机制进行说明。包括:术语、索引的机制、视图索引的选项说明。
    说明
    视图索引的机制
    第1章概述
    本文档主要是对视图的索引机制进行说明。包括:术语、索引的机制、视图索引的选项说明。
    文档中用到的术语:
    更新(Refresh):按F9可以刷新视图的索引。Refresh读视图的索引并刷新用户的屏幕。它不会重建视图的索引。
    重建(Rebuild):按Shift+F9可以重建视图的索引。重建视

  • 虚函数后面的分号可有可无_虚函数需要实现吗

    虚函数后面的分号可有可无_虚函数需要实现吗const 和 =0要分开理解.首先理解一下分开的意思成员函数后面用 const 修饰,const表示this是一个指向常量的指针,即对象成为一个常量,即它的成员不能够变化.(默认情况下,this的类型是指向类类型非常量版本的常量指针。例如在Sales_data成员函数中,this的类型是Sales_data *const,即类一旦实例化一个对象后,this指向这个对象,是不能改变的,但是对象…

  • 2021github仓库操作流程手册指南「建议收藏」

    2021github仓库操作流程手册指南「建议收藏」文章目录1.git操作2.git简介3.git安装4.git使用1.git初始化2.git设置用户信息3.git项目的拉取1.创建仓库2.本地初始化3.查看当前是否存在自己的账号信息并配置(包含步骤4)4.基础配置5.初始化内容6.开始引入自己的项目的地址7.更新操作8.git文件的添加保存和推送到github9.git文件的修改删除推送github10.gitpush操作每次都需要输入账号密码的解决办法5.总结至此git的仓库创建,仓库拉取到本地,文件的添加修改删除提交已经完成。其中遇到

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号