vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue.js登录功能

基于Vue.js实现一个完整的登录功能

作者:码农阿豪@新空间

在现代Web应用中,用户登录功能是一个核心模块,它不仅涉及到用户身份验证,还需要处理表单验证、状态管理、接口调用等多个环节,本文将基于一个Vue.js项目中的登录功能实现,深入解析其背后的技术细节,帮助开发者更好地理解和实现类似功能,需要的朋友可以参考下

1. 引言

用户登录功能是Web应用中最常见的功能之一。它通常包括表单输入、数据验证、接口调用、状态管理等多个步骤。在Vue.js中,我们可以通过组合使用Vue组件、Vuex状态管理、Axios网络请求等技术来实现一个完整的登录功能。

本文将基于一个实际的Vue.js项目代码,详细解析登录功能的实现过程。我们将从表单的实现开始,逐步深入到表单验证、接口调用、状态管理以及登录成功与失败的处理。

2. 项目结构概述

在开始之前,我们先简单了解一下项目的结构。项目的登录功能主要由以下几个部分组成:

3. 登录表单的实现

登录表单是用户与系统交互的入口。在我们的项目中,登录表单使用了Ant Design Vue组件库来实现。以下是登录表单的核心代码:

<template>
  <a-col class="main line_input">
    <a-form
      id="formLogin"
      class="user-layout-login"
      ref="formLogin"
      :form="form"
      hideRequiredMark
      @submit="handleSubmit"
    >
      <div class="title"><span>1nmob</span></div>
      <a-alert v-if="isLoginError" type="error" showIcon style="margin-bottom: 24px;" message="账户或密码错误" />

      <!-- 登录方式选择 -->
      <a-radio-group v-model="loginType" style="margin-bottom: 24px;">
        <a-radio-button value="account">账号密码登录</a-radio-button>
        <a-radio-button value="phone">手机号登录</a-radio-button>
      </a-radio-group>

      <!-- 账号密码登录 -->
      <div v-if="loginType === 'account'">
        <a-row type="flex" class="padding_bottom">
          <a-col flex="58px">
            <span class="labels">账号:</span>
          </a-col>
          <a-col flex="310px">
            <a-form-item>
              <a-input
                size="small"
                type="text"
                placeholder=""
                ref="userCodeDom"
                v-decorator="[
                  'userCode',
                  {rules: [{ required: true, message: '请输入帐户名或邮箱地址' }, { validator: handleuserCodeOrEmail }], validateTrigger: 'change'}
                ]"
              >
              </a-input>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row type="flex">
          <a-col flex="58px">
            <span class="labels">密码:</span>
          </a-col>
          <a-col flex="310px">
            <a-form-item>
              <a-input-password
                size="small"
                class="my_password"
                placeholder=""
                ref="pwdDom"
                v-decorator="[
                  'pwd',
                  {rules: [{ required: true, message: '请输入密码' }], validateTrigger: 'blur'}
                ]"
              >
              </a-input-password>
            </a-form-item>
          </a-col>
        </a-row>
      </div>

      <!-- 手机号登录 -->
      <div v-if="loginType === 'phone'">
        <a-row type="flex" class="padding_bottom">
          <a-col flex="58px">
            <span class="labels">手机号:</span>
          </a-col>
          <a-col flex="310px">
            <a-form-item>
              <a-input
                size="small"
                type="text"
                placeholder=""
                ref="phoneDom"
                v-decorator="[
                  'phone',
                  {rules: [{ required: true, message: '请输入手机号' }], validateTrigger: 'change'}
                ]"
              >
              </a-input>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row type="flex">
          <a-col flex="58px">
            <span class="labels">验证码:</span>
          </a-col>
          <a-col flex="200px">
            <a-form-item>
              <a-input
                size="small"
                type="text"
                placeholder=""
                ref="captchaDom"
                v-decorator="[
                  'captcha',
                  {rules: [{ required: true, message: '请输入验证码' }], validateTrigger: 'blur'}
                ]"
              >
              </a-input>
            </a-form-item>
          </a-col>
          <a-col flex="110px">
            <a-button
              size="small"
              :disabled="state.smsSendBtn"
              @click="getCaptcha"
            >
              {{ state.smsSendBtn ? `${state.time}秒后重新获取` : '获取验证码' }}
            </a-button>
          </a-col>
        </a-row>
      </div>

      <a-form-item>
        <router-link
          :to="{ name: 'recover', params: { user: 'aaa'} }"
          class="forge-password"
          style="float: right;"
        >忘记密码?</router-link>
      </a-form-item>
      <div style="textAlign:center">
        <a-form-item style="margin-bottom:0px">
          <a-button
            size="large"
            type="primary"
            htmlType="submit"
            class="login-button"
            :loading="state.loginBtn"
            :disabled="state.loginBtn"
          >确定</a-button>
        </a-form-item>
      </div>
    </a-form>
  </a-col>
</template>

在这个表单中,我们使用了a-form组件来包裹整个表单,并通过v-decorator指令来实现表单验证。用户可以选择通过账号密码或手机号登录,表单会根据用户的选择动态渲染不同的输入项。

4. 表单验证

表单验证是确保用户输入数据合法性的重要步骤。在我们的项目中,表单验证通过Ant Design Vue的v-decorator指令来实现。以下是表单验证的核心代码:

methods: {
  handleuserCodeOrEmail (rule, value, callback) {
    const { state } = this
    const regex = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/
    if (regex.test(value)) {
      state.loginType = 0
    } else {
      state.loginType = 1
    }
    callback()
  },
  handleSubmit (e) {
    e.preventDefault()
    const {
      form: { validateFields },
      state,
      loginType,
      Login
    } = this
    state.loginBtn = true

    const validateFieldsKey = loginType === 'account' ? ['userCode', 'pwd'] : ['phone', 'captcha']

    validateFields(validateFieldsKey, { force: true }, (err, values) => {
      if (!err) {
        const loginParams = { ...values }
        if (loginType === 'account') {
          delete loginParams.userCode
          loginParams[!state.loginType ? 'email' : 'userCode'] = values.userCode
          loginParams.pwd = md5(values.pwd)
        } else {
          loginParams.phone = values.phone
          loginParams.captcha = values.captcha
        }
        Login(loginParams)
          .then((res) => {
            if (res.code === this.CONSTVAL.SUCCESSCODE) {
              this.loginSuccess(res)
            } else {
              this.requestFailed(res)
            }
          })
          .catch(err => this.requestFailed(err))
          .finally(() => {
            state.loginBtn = false
          })
      } else {
        setTimeout(() => {
          state.loginBtn = false
        }, 600)
      }
    })
  }
}

handleSubmit方法中,我们首先调用validateFields方法对表单进行验证。如果验证通过,则构造登录参数并调用Login方法进行登录。

5. 登录接口的调用

登录接口的调用是通过Vuex的action来实现的。以下是登录接口调用的核心代码:

methods: {
  ...mapActions(['Login', 'Logout']),
  handleSubmit (e) {
    e.preventDefault()
    const {
      form: { validateFields },
      state,
      loginType,
      Login
    } = this
    state.loginBtn = true

    const validateFieldsKey = loginType === 'account' ? ['userCode', 'pwd'] : ['phone', 'captcha']

    validateFields(validateFieldsKey, { force: true }, (err, values) => {
      if (!err) {
        const loginParams = { ...values }
        if (loginType === 'account') {
          delete loginParams.userCode
          loginParams[!state.loginType ? 'email' : 'userCode'] = values.userCode
          loginParams.pwd = md5(values.pwd)
        } else {
          loginParams.phone = values.phone
          loginParams.captcha = values.captcha
        }
        Login(loginParams)
          .then((res) => {
            if (res.code === this.CONSTVAL.SUCCESSCODE) {
              this.loginSuccess(res)
            } else {
              this.requestFailed(res)
            }
          })
          .catch(err => this.requestFailed(err))
          .finally(() => {
            state.loginBtn = false
          })
      } else {
        setTimeout(() => {
          state.loginBtn = false
        }, 600)
      }
    })
  }
}

handleSubmit方法中,我们通过Login action来调用登录接口。Login action会在Vuex store中定义,通常使用Axios来发送HTTP请求。

6. Vuex状态管理

Vuex是Vue.js的官方状态管理库,用于管理应用中的共享状态。在我们的项目中,Vuex负责管理用户登录状态。以下是Vuex store的核心代码:

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    user: null,
    token: null
  },
  mutations: {
    setUser (state, user) {
      state.user = user
    },
    setToken (state, token) {
      state.token = token
    }
  },
  actions: {
    Login ({ commit }, loginParams) {
      return axios.post('/api/login', loginParams)
        .then(response => {
          commit('setUser', response.data.user)
          commit('setToken', response.data.token)
          return response
        })
    },
    Logout ({ commit }) {
      commit('setUser', null)
      commit('setToken', null)
    }
  }
})

在Vuex store中,我们定义了LoginLogout两个action,分别用于处理登录和注销操作。登录成功后,我们会将用户信息和token存储到state中。

7. 登录成功与失败的处理

登录成功或失败后,我们需要根据接口返回的结果进行相应的处理。以下是登录成功与失败处理的代码:

methods: {
  loginSuccess (res) {
    this.setUserCode(res.data.userCode)
    this.setAccessWay(res.data.accessWay)
    this.setUserPic(res.data.userPic)
    this.setCompanyId(res.data.companyId)
    this.setAccountType(res.data.accessWay)
    this.setTokenTime(res.data.tokenTime)
    this.$router.push({ path: '/' })
    setTimeout(() => {
      this.$notification.success({
        message: '欢迎',
        description: `${timeFix()},欢迎回来`
      })
    }, 1000)
    this.isLoginError = false
  },
  requestFailed (err) {
    this.isLoginError = true
    this.$notification['error']({
      message: '错误',
      description: ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试',
      duration: 4
    })
  }
}

loginSuccess方法中,我们将用户信息存储到Vuex state中,并跳转到首页。在requestFailed方法中,我们显示错误信息,提示用户登录失败。

8. 总结

通过本文的详细解析,我们了解了如何在Vue.js项目中实现一个完整的登录功能。我们从表单的实现开始,逐步深入到表单验证、接口调用、状态管理以及登录成功与失败的处理。希望本文能帮助开发者更好地理解和实现类似功能。

在实际开发中,登录功能可能会更加复杂,涉及到更多的安全性和用户体验优化。但无论如何,掌握这些基础知识是构建一个健壮的登录功能的前提。

以上就是基于Vue.js实现一个完整的登录功能的详细内容,更多关于Vue.js登录功能的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文