人力资源智能化管理项目(day02:登录模块)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/humanResourceIntelligentManagementProject

觉得有帮助的同学,可以点心心支持一下哈

登录页的结构和表单

准备登录页面的样式和结构

拷贝登录页的基本结构布局-代码位置(src/views/login/index.vue)

<template>
  <div class="login-container">
    <div class="logo" />
    <div class="form">
      <h1>登录</h1>
      <el-card shadow="never" class="login-card">
        <!--登录表单-->
      </el-card>
    </div>
  </div>
</template>
<script>
  export default {
    name : "Login"
  }
</script>
<style lang="scss">
  .login-container {
    display: flex;
    align-items: stretch;
    height: 100vh;
    .logo {
      flex: 3;
      background: rgba(38, 72, 176) url(../../assets/common/login_back.png)
        no-repeat center / cover;
      border-top-right-radius: 60px;
      display: flex;
      flex-direction: column;
      align-items: flex-end;
      justify-content: center;
      padding: 0 100px;
      .icon {
        background: url(../../assets/common/logo.png) no-repeat 70px center /
          contain;
        width: 300px;
        height: 50px;
        margin-bottom: 50px;
      }
      p {
        color: #fff;
        font-size: 18px;
        margin-top: 20px;
        width: 300px;
        text-align: center;
      }
    }
    .form {
      flex: 2;
      display: flex;
      flex-direction: column;
      justify-content: center;
      padding-left: 176px;
      .el-card {
        border: none;
        padding: 0;
      }
      h1 {
        padding-left: 20px;
        font-size: 24px;
      }
      .el-input {
        width: 350px;
        height: 44px;
        .el-input__inner {
          background: #f4f5fb;
        }
      }
      .el-checkbox {
        color:#606266;
      }
    }
  }
</style>

实现登录表单的结构

<el-form>
          <el-form-item>
            <el-input placeholder="请输入手机号" />
          </el-form-item>
          <el-form-item>
            <el-input type="password" placeholder="请输入密码" />
          </el-form-item>
          <el-form-item>
            <el-checkbox> 用户平台使用协议 </el-checkbox>
          </el-form-item>
          <el-form-item>
            <el-button style="width: 350px" type="primary">登录</el-button>
          </el-form-item>
        </el-form>

实现登录表单校验

ref、:model、:rules、prop

<el-form
          ref="form"
          autocomplete="off"
          :model="loginForm"
          :rules="loginRules"
        >
          <el-form-item prop="mobile">
            <el-input v-model="loginForm.mobile" placeholder="请输入手机号" />
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model="loginForm.password"
              type="password"
              placeholder="请输入密码"
            />
          </el-form-item>
          <el-form-item prop="isAgree">
            <el-checkbox v-model="loginForm.isAgree">
              用户平台使用协议
            </el-checkbox>
          </el-form-item>
          <el-form-item>
            <el-button style="width: 350px" type="primary" @click="login"
              >登录</el-button
            >
          </el-form-item>
        </el-form>

手机号 必填,手机号规则;密码 必填,6-16位长度;用户协议 必须勾选

      loginForm: {
        mobile: '',
        password: '',
        isAgree: false
      },
      loginRules: {
        mobile: [
          {
            required: true,
            message: '请输入手机号',
            trigger: 'blur'
          },
          {
            pattern:
              /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
            message: '手机号格式不正确',
            trigger: 'blur'
          }
        ],
        password: [
          {
            required: true,
            message: '请输入密码',
            trigger: 'blur'
          },
          {
            min: 6,
            max: 16,
            message: '密码长度应该为6-12之间',
            trigger: 'blur'
          }
        ],
        // required只能检测null undefined ""
        isAgree: [
          {
            validator: (rule, value, callback) => {
              // rule校验规则
              // value检验的值
              // callback函数-promise reslove reject
              // callback() callback(new Error(错误信息))
              value ? callback() : callback(new Error('您必须勾选协议'))
            }
          }
        ]
      }

表单整体校验

    login () {
      this.$refs.form.validate(isOk => {
        if (isOk) {
          alert('校验通过')
        }
      })
    }

分析登录流程

Vuex用户模块

在src/store/modules/user.js中管理token

实现token的Vuex数据持久化

实现登录的action方法

import { getToken, setToken, removeToken } from '@/utils/auth'
const state = {
  token: getToken() // 从缓存中读取初始值
}
const mutations = {
  setToken (state, token) {
    state.token = token
    // 同步到缓存
    setToken(token)
  },
  removeToken (state) {
    // 删除Vuex的token
    state.token = null
    removeToken()
  }
}
const actions = {
  // context上下文,传入参数
  login (context, data) {
    console.log(data)
    // 调用登录接口
    // 放回一个token 123456
    context.commit('setToken', '123456')
  }
}
export default {
  namespaced: true, // 开启命名空间
  state,
  mutations,
  actions
}

调用VuexAction

login () {
      this.$refs.form.validate(isOk => {
        if (isOk) {
          this.$store.dispatch('user/login', this.loginForm)
        }
      })
    }

vue-cli代理解决跨域

原理:代理服务器和浏览器是同源的,服务器与服务器之间不存在同源策略,所以代理服务器可以和后端服务器进行请求

vue.config.js(改完要重启),注意删除原有的before配置选项

  proxy: {
      // path: 目标服务器 百度 新浪 网易 ...
      '/api': {
        target: 'https://heimahr.itheima.net/' // 要代理的目标地址
      }
    }
    // before: require('./mock/mock-server.js') 基础模板做的模拟数据 拦截请求

发请求验证

<el-button @click="testAjax">测试接口</el-button>

import axios from 'axios'
    testAjax () {
      axios({
        // url: 'https://heimahr.itheima.net/api/sys/login',
        url: '/api/sys/login', // http://localhost:9528/api/sys/login =>https://heimahr.itheima.net/api/sys/login
        method: 'post',
        data: {
          mobile: '13800000002',
          password: 'hm#qd@23!'
        }
      })
    }

成功截图

axios封装

axios封装的需求

axios功能

基础配置(基地址,超时);请求拦截器,响应拦截器

import axios from 'axios'
import store from '@/store'
import { Message } from 'element-ui'

// 创建一个新的axios实例
const service = axios.create({
  baseURL: '/api', // 基地址
  timeout: 10000 // 超时时间
})
// 请求拦截器,成功执行第一个,失败执行第二个
service.interceptors.request.use(
  config => {
    // 注入token
    // store.getters.token=>请求头里面
    if (store.getters.token) {
      config.headers.Authorization = `Bearer ${store.getters.token}`
    }
    return config
  },
  error => {
    // 失败执行promise
    return Promise.reject(error)
  }
)
// 响应拦截器
service.interceptors.response.use(
  response => {
    // axios默认包裹了data
    const { data, message, success } = response.data
    if (success) {
      return data
    } else {
      Message({
        type: 'error',
        message: message
      })
      return Promise.reject(new Error(message))
    }
  },
  error => {
    Message({
      type: 'error',
      message: error.message
    })
    return Promise.reject(error)
  }
)
export default service

发请求验证

<el-button @click="testAxios">测试axios封装</el-button>
import request from '@/utils/request'
testAxios () {
      request({
        url: '/sys/login',
        method: 'post',
        data: {
          mobile: '13800000002',
          password: 'hm#qd@23!'
        }
      })
    }

环境区分

axios的请求处理基地址

开发环境配置变量

# just a flag
ENV = 'development'

# base api
VUE_APP_BASE_API = '/api'
import axios from 'axios'
import store from '@/store'
import { Message } from 'element-ui'

// 创建一个新的axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // 基地址
  timeout: 10000 // 超时时间
})

登录联调

1.封装API请求

import request from '@/utils/request'
export function login (data) {
  return request({
    url: '/sys/login',
    method: 'post',
    data // body参数位于data
  })
}

2.Vuex调用

const actions = {
  // context上下文,传入参数
  async login (context, data) {
    // console.log(data)
    // 调用登录接口
    const token = await login(data)
    // 放回一个token 123456
    context.commit('setToken', token)
  }
}

3.跳转主页

async login () {
      this.$refs.form.validate(async isOk => {
        if (isOk) {
          await this.$store.dispatch('user/login', this.loginForm)
          // Vuex中的action返回的是promise
          // 跳转主页
          this.$router.push('/')
        }
      })
    }

4.区分环境数据

loginForm: {
        mobile: process.env.NODE_ENV === 'development' ? '13800000002' : '',
        password: process.env.NODE_ENV === 'development' ? 'hm#qd@23!' : '',
        isAgree: process.env.NODE_ENV === 'development'
      }
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值