第二节:基础配置(路由、less、静态资源、axios、ESLint)、基础组件(Form、Message) 之登录页面搭建

一.基础配置

1. 路由配置

(1). 创建项目,已经引入了Vue-Router,这里的版本为:3.2.0,并自动创建了router→index.js文件。

(2). 在index.js文件中:

 A. 导入vue、vue-router

 B. 导入其它子页面

 C. 配置路由规则,默认进入/login登录页面,home页面下配置子路由,home页面需要添加路由占位符

<router-view></router-view>

 D. 挂载路由导航守卫,token不存在的话,不允许单独跳转到除了login以外的页面,同意跳转到登录页面。

 E. 默认对外导出

代码分享:

import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入各个子页面(可以用相对路径 或 根路径,@代表根路径)
import Login from '../components/Login.vue'
import Home from '@/components/Home.vue'
import Welcome from '@/components/Welcome.vue'
import Users from '@/components/user/Users.vue'
import Rights from '@/components/power/Rights.vue'
import Roles from '@/components/power/Roles.vue'
import Params from '@/components/goods/Params.vue'
import GoodsList from '@/components/goods/List.vue'
import Add from '@/components/goods/Add.vue'
import Order from '@/components/order/Order.vue'
import Report from '@/components/report/Report.vue'

Vue.use(VueRouter)

const router = new VueRouter({
  routes: [{
      path: '/',
      redirect: '/login'
    },
    {
      path: '/login',
      component: Login
    },
    {
      path: '/home',
      component: Home,
      redirect: '/welcome',
      children: [{
          path: '/welcome',
          component: Welcome
        },
        {
          path: '/users',
          component: Users
        },
        {
          path: '/rights',
          component: Rights
        },
        {
          path: '/roles',
          component: Roles
        },
        {
          path: '/params',
          component: Params
        },
        {
          path: '/goods',
          component: GoodsList
        },
        {
          path: '/goods/add',
          component: Add
        },
        {
          path: '/orders',
          component: Order
        },
        {
          path: '/reports',
          component: Report
        }
      ]
    }
  ]
})


// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
  // to 将要访问的路径
  // from 代表从哪个路径跳转而来
  // next 是一个函数,表示放行
  // next()  放行    next('/login')  强制跳转
  if (to.path === '/login') return next()
  // 获取token
  const tokenStr = window.sessionStorage.getItem('token')
  if (!tokenStr) return next('/login')
  next()
})


// 默认导出
export default router
View Code

PS. 如何手动调用跳转:

this.$router.push('/home')

2. 样式配置

(1). 项目中要用到less语法,所以需要安装less 和 less-loader,开发依赖

【npm install less -D】      (4.1.1)

【npm install less-loader@7.x -D】   (7.3.0)不能装太高版本

(2) style标签中增加 lang="less",表示支持less语法,另外增加scoped属性,代表写的样式仅当前页面有效。

<style lang="less" scoped></style>

3. 静态资源

 静态资源,比如全局样式、第三方字体文件等,统一放在 src下的assets文件夹中。然后在main.js文件中导入全局样式和第三方字体。

// 导入字体图标
import './assets/fonts/iconfont.css'
// 导入全局样式表
import './assets/css/global.css' 

4. axios封装和使用

(1). 通过指令【npm install axios -save】进行安装

(2). 在main.js中进行导入

(3). 配置baseURL、请求拦截中添加表头(存放token)、利用Vue.prototype进行全局对象封装为$http。

代码分享:

// 导入axios并进行配置
import axios from 'axios'
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
axios.interceptors.request.use(config => {
  // 添加表头信息
  config.headers.Authorization = window.sessionStorage.getItem('token');
  return config;
})
Vue.prototype.$http = axios

(4).使用:以post请求为例,借助async和await,干掉回调,以同步的编码方式进行获取,然后利用解构赋值,拿到返回对象中的data属性(注意,不是接口返回值的data),然后起别名为res。

async login () {
   const {
     data: res
   } = await this.$http.post('login', this.loginForm)
   if (res.meta.status !== 200) return this.$message.error('登录失败!')
   this.$message.success('登录成功')
}

5. ESLint警告处理

创建项目的时候,选择安装了ESLint,相关程序集如下:

(1). 运行指令【npm run lint】或者(npm run serve), 会报很多错误和警告,如下图:

但有些警告我们并不像处理,也不想让它提示,那么就在根目录下的 .eslintrc.js 文件中进行关闭 

 rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    // 禁止超过1个空行报错规则,0代表关掉
    'no-multiple-empty-lines': 0,
    'no-tabs': 0,
    'eslint-disable-next-line': 0,
    'space-before-function-paren':0,
    'indent':0

  }

(2). 如果你想更加简单粗暴的关掉验证,可以新增一个.eslintignore文件,直接关掉 .vue文件和 .js文件的验证。

*.vue
*.js

 

二. 基础组件

1. Form表单

(1). 获取表单对象

 在el-form中新加一个ref=“loginFormRef”属性,然后通过 this.$refs.loginFormRef 就可以获取该对象了,可以调用该对象的相关方法。 

PS:这是一种通用的方式,适用于任何element组件。 

(2). 值绑定 

 在el-form中通过 :model="loginForm"进行整个对象的绑定,然后在对应 input标签中通过 v-model="loginForm.username"进行子属性的绑定。 

 

(3).验证规则绑定(含自定义验证)

  在el-form中通过 :rules="loginFormRules"进行整个验证规则对象的绑定,然后在对应el-form-item标签中通过 prop="属性值" 进行子属性规则的绑定。 

PS 自定义验证规则:

 需要自定义一个方法,方法有3个参数,rule、value、callback,重点是后两个;value是验证的内容,callback是回调,验证通过,直接返回 callback(); 验证不通过,则声明 callback(new Error('请输入数字值'));

然后定义的方法赋给validator属性。

代码如下:

<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
  <el-form-item label="密码" prop="pass">
    <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="确认密码" prop="checkPass">
    <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
  </el-form-item>
  <el-form-item label="年龄" prop="age">
    <el-input v-model.number="ruleForm.age"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
    <el-button @click="resetForm('ruleForm')">重置</el-button>
  </el-form-item>
</el-form>
<script>
  export default {
    data() {
      var checkAge = (rule, value, callback) => {
        if (!value) {
          return callback(new Error('年龄不能为空'));
        }
        setTimeout(() => {
          if (!Number.isInteger(value)) {
            callback(new Error('请输入数字值'));
          } else {
            if (value < 18) {
              callback(new Error('必须年满18岁'));
            } else {
              callback();
            }
          }
        }, 1000);
      };
      var validatePass = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          if (this.ruleForm.checkPass !== '') {
            this.$refs.ruleForm.validateField('checkPass');
          }
          callback();
        }
      };
      var validatePass2 = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请再次输入密码'));
        } else if (value !== this.ruleForm.pass) {
          callback(new Error('两次输入密码不一致!'));
        } else {
          callback();
        }
      };
      return {
        ruleForm: {
          pass: '',
          checkPass: '',
          age: ''
        },
        rules: {
          pass: [
            { validator: validatePass, trigger: 'blur' }
          ],
          checkPass: [
            { validator: validatePass2, trigger: 'blur' }
          ],
          age: [
            { validator: checkAge, trigger: 'blur' }
          ]
        }
      };
    },
    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            alert('submit!');
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>
View Code 

(4). 表单校验

 调用validate进行表单内所有内容的校验

this.$refs.loginFormRef.validate(valid => {
        console.log(valid)
        if (!valid) return
        // 下面表示校验通过,进行业务编写
  
 })

(5). 表单重置 

this.$refs.loginFormRef.resetFields()

2. Message消息提示 

(1). 全局引入和封装

import { Message } from 'element-ui'
Vue.prototype.$message = Message

(2). 使用 

this.$message.success('登录成功')
this.$message.error('登录失败!')

 this.$message({
          showClose: true,
          message: '错了哦,这是一条错误消息',
          type: 'error'
});

 

三. 登录界面

1. 效果分享

 

2. 代码分享

<template>
  <div class="login_container">
    <div class="login_box">
      <!-- 头像区域 -->
      <div class="avatar_box">
        <img src="../assets/logo.png" alt="">
      </div>
      <!-- 登录表单区域 -->
      <el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form">
        <!-- 用户名 -->
        <el-form-item prop="username">
          <el-input v-model="loginForm.username" prefix-icon="iconfont icon-user"></el-input>
        </el-form-item>
        <!-- 密码 -->
        <el-form-item prop="password">
          <el-input v-model="loginForm.password" prefix-icon="iconfont icon-3702mima" type="password">
          </el-input>
        </el-form-item>
        <!-- 按钮区域 -->
        <el-form-item class="btns">
          <el-button type="primary" @click="login">登录</el-button>
          <el-button type="info" @click="resetLoginForm">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      // 这是登录表单的数据绑定对象
      loginForm: {
        username: 'admin',
        password: '123456'
      },
      // 这是表单的验证规则对象
      loginFormRules: {
        // 验证用户名是否合法
        username: [{
          required: true,
          message: '请输入登录名称',
          trigger: 'blur'
        },
        {
          min: 3,
          max: 10,
          message: '长度在 3 到 10 个字符',
          trigger: 'blur'
        }
        ],
        // 验证密码是否合法
        password: [{
          required: true,
          message: '请输入登录密码',
          trigger: 'blur'
        },
        {
          min: 6,
          max: 15,
          message: '长度在 6 到 15 个字符',
          trigger: 'blur'
        }
        ]
      }
    }
  },
  methods: {
    // 1.重置事件
    resetLoginForm () {
      // 通过$refs可以达到表单中ref的属性值
      this.$refs.loginFormRef.resetFields()
    },
    // 2. 登录事件
    login () {
      // 2.1 先对整个form表单进行规则校验
      this.$refs.loginFormRef.validate(async valid => {
        console.log(valid)
        if (!valid) return
        // 2.2 校验通过,发送请求
        const {
          data: res
        } = await this.$http.post('login', this.loginForm)
        if (res.meta.status !== 200) return this.$message.error('登录失败!')
        this.$message.success('登录成功')
        // 2.3. 将登录成功之后的 token,保存到客户端的 sessionStorage 中
        // 2.3.1 项目中出了登录之外的其他API接口,必须在登录之后才能访问
        // 2.3.2 token 只应在当前网站打开期间生效,所以将 token 保存在 sessionStorage 中
        window.sessionStorage.setItem('token', res.data.token)
        // 2.4  通过编程式导航跳转到后台主页,路由地址是 /home
        this.$router.push('/home')
      })
    }
  }
}
</script>

<style lang="less" scoped>
  .login_container {
    background-color: #2b4b6b;
    height: 100%;
  }

  .login_box {
    width: 450px;
    height: 300px;
    background-color: #fff;
    border-radius: 3px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);

    .avatar_box {
      height: 130px;
      width: 130px;
      border: 1px solid #eee;
      border-radius: 50%;
      padding: 10px;
      box-shadow: 0 0 10px #ddd;
      position: absolute;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: #fff;

      img {
        width: 100%;
        height: 100%;
        border-radius: 50%;
        background-color: #eee;
      }
    }
  }

  .login_form {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 0 20px;
    box-sizing: border-box;
  }

  .btns {
    display: flex;
    justify-content: flex-end;
  }
</style>
View Code

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2021-03-19 20:27  Yaopengfei  阅读(382)  评论(0编辑  收藏  举报