Vue3入门笔记----登录功能

这篇具有很好参考价值的文章主要介绍了Vue3入门笔记----登录功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


这个系列的笔记重点会放在怎么样利用Vue3把项目架设起来并跟后端API互动,不会介绍Vue的基础特性,关于Vue的基础特性可以参考这个视频 四个小时带你快速入门Vue,我是看这个入门的,觉得还不错。

代码地址: https://github.com/yexia553/vue_study/tree/%E9%85%8D%E7%BD%AEvue-router/vue3-notes

这篇笔记的内容有点难,建议多看几遍

笔记中的代码一定要结合github仓库的内容和博客中提到的视频一起看,不然不太容易看懂

这篇笔记中新使用了好几个第三方包,建议新手在看博客内容之前现在项目根目录下执行以下cnpm install 安装这些依赖,以免后面报错

同步发表于个人站点: http://panzhixiang.cn/article/2022/11/15/61.html

登录功能介绍

很多网站都有登录功能,访问者在页面上输入账号密码之后页面会请求后端API进行认证,如果认证通过会跳转到首页。我们简单地来拆分一下这个过程中具体有那几件事情。

  1. 首先要有一个登录页面让访问者输入账号密码,并且要有登录按钮
  2. 后端要有一个认证相关的API用来给页面调用以检查访问者提供的账号密码是否正确
  3. 上一步的认证检查通过之后,前端会获得一个token,这个token标志着访问者是合法的,需要把这个token存储起来,以便在后面请求后端的时候使用

以上就是实现一个登录功能大致的过程。在这个过程中会用到axios来调用API,另外后端的认证用的jwt,还需要vuex来做状态管理,我会在下面分别介绍这三个知识点。

axios请求API和axios的封装

做前端开发的人肯定听说过axios,关于axios的介绍我就不写了,网上有很多相关的内容。

原生的axios在调用API的时候每一次都要写很多代码,我做了一点封装,代码放在src/api/request.js中,


import axios from 'axios'
import config from './config.js'
import Cookies from 'js-cookie'
import { ElMessage } from 'element-plus'
import store from '../store/index.js'
import { useRouter } from 'vue-router';


const NETWORK_ERROR = '网络请求错误,请稍后重试...'


const service = axios.create({
    baseURL: config.baseApi,
})

service.interceptors.request.use((req) => {
    //可以在请求之前做一些事情
    //比如自定义header, jwt-token等等
    return req
})

service.interceptors.response.use((res) => {
    // 对请求得到的响应做一些处理
    if (res.status === 200) {
        // 状态码是200表明请求正常,可以返回请求到的数据也可以做一些其他事情
        return res
    } else {
        // 状态码不是200说明请求可能出错
        // ElMessage.error(NETWORK_ERROR)
        // return Promise.reject(NETWORK_ERROR)
        // 这里的封装不完善,直接抛出异常会导致页面不能正常提醒用户,先这样返回,以后修改
        return res
    }
})

let tokenRefresher = async () => {
    let router = useRouter()
    let now = new Date().getTime()
    if (now - Cookies.get('last_token_refresh_time') > 1000 * 60 * 4) {
        let res = await service({
            url: '/api/token/refresh/',
            method: 'post',
            headers: {
                'Authorization': `Bearer ${Cookies.get('access_token')}`
            },
            data: {
                refresh: `${Cookies.get('refresh_token')}`
            }
        })
        if (res.status === 200) {
            store.commit('setAccessToken', res.data.access)
        } else if (res.status === 403) {
            // refresh token过期了,要求重新登录
            store.commit('clearRefreshToken')
            store.commit('clearAccessToken')
            router.push({
                name: 'login'
            })
        }
    }
}

function request(options) {
    options.method = options.method || 'get' // 如果没有传入method这个参数,就默认是get请求
    if (options.method.toLowerCase() === 'get') {
        // console.log(options)
        options.params = options.data
    }
    // 如果可以从cookie中获取到access_token,就添加到header中
    if (Cookies.get('access_token')) {
        // 设置token之前先检查是否需要更新token
        tokenRefresher()
        service.defaults.headers.common['Authorization'] = `Bearer ${Cookies.get('access_token')}`
    }
    return service(options)
}

export default request

其实这一部分封装的不好,几乎没什么额外的功能,但是整个封装的思路都在里面了,强烈建议结合Vue3中如何封装axios 这个视频一起理解axios封装的部分,在实际工作中还是很有用的,在我接触axios封装之前就是在每一次调用的api的时候写一堆重复的代码,修改布置后确实方便很多。

上面这一段代码中的tokenRefresher这个函数是用来更新access token的,暂时可以先不管,等看完后面的jwt和api部分在回头理解这一部分。

jwt的介绍和在登录功能中的应用

在看下面的内容之前,推荐先完整仔细地看一下下面两篇博客:

  1. JSON Web Token 入门教程 ---- 阮一峰
  2. JWT 介绍 - Step by Step

可以不用细究里面的细节,了解运行过程即可。

我简单的概括一下jwt在登录这个场景中过程,以便理解后面的内容。

  1. 访问者在页面上输入账号密码并点击登录之后前端会请求后端的/api/token/这个api,如果认证通过,后端会给前端返回一个access token和一个refresh token
  2. access token是用来访问后端api的,所以在之后的请求中都要携带这个token才能正常访问api;refresh token是用来刷新access token的,因为一般来说,access token的有效期很多,比如django 的DRF框架中,默认情况下,access token的有效期只有5分钟,但是refresh token的有效期是8个小时
  3. 前端拿到access token和refresh token 需要找一个地方把它们存储起来,以便后面使用,比如可以存在cookie中,或者是localstorage中等
  4. 要有一个检查机制,检查access token有没有过期,如果过期了就要及时用refresh token进行更新,获取新的access token,并且还要更新在上一步存存储的access token

vue3中api的集中管理

在前后端分离的情况下,前端一般都需要一个方法来管理被调用的API,这样比较便于后期的维护、更新和修改等工作,这里介绍一种我比较喜欢的方法,这个方式使用于中小型的前端项目,调用的API不是非常多的情况。

  1. 首先在src/api目录下新建一个config.js文件,内容如下,
/**
 * 项目的环境配置
 */
// 这是vite的一种使用方式:https://cn.vitejs.dev/guide/env-and-mode.html#env-files
const env = import.meta.env.MDOE || 'dev'

const envConfig = {
    dev: {
        baseApi: 'http://localhost:8000',
    },
    test: {
        baseApi: 'test.example.com/api',
    },
    prod: {
        baseApi: 'example.com/api',
    }
}

export default {
    env,
    ...envConfig[env]
}

不难看出,这个文件是用来做环境管理的,比如第一个dev表示本地的开发环境,test表示线上测试环境,prod表示生产环境,还可以按照自己的需要添加其他的配置。
这个config.js在前面axios的封装中也有用到,大家可以回到上面看一下代码。

  1. 然后在src/api目录下创建一个api.js文件,这个文件就是用来放置所有会被调用的api的地方,代码如下,
import request from "./request.js";


export default {
    login(params) {
        return request({
            url: '/api/token/',
            method: 'post',
            data: params,
            mock: false
        })
    },
    refreshToken(params) {
        return request({
            url: '/api/token/refresh',
            method: 'post',
            data: params,
            mock: false
        })
    }
}

api.js里面目前只包含两个接口,一个是login,用于在登录的时候调用,一个是refreshtoken,用于刷新access token, 这个在上面jwt部分介绍过。

  1. 创建了api.js之后,还需要把它跟vue绑定起来,这样才能调用。
    修改src/main.js这个文件,修改后如下,

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import router from './router/index.js'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import './assets/main.css'
import api from './api/api.js'


const app = createApp(App)

for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
}

app.use(router)
app.use(ElementPlus)
app.mount('#app')
app.config.globalProperties.$api = api

修改的部分就是在import里面引入src/api/api.js;然后在最后一行把api配置到vue的global properties,方便以后引用。

到这里vue中api的集中管理就结束了。

登录页面的实现

上面做了那么多准备工作,都是为了实现登录页面做的,我们现在来实现它。在src/views目录下创建login文件夹,然后在其中创建Login.vue文件,文件内容如下,主要看代码中的注释。

<template>
    <el-form :model="formData" status-icon class="login-container" ref="formRef">
        <h3 class="login-title">登陆</h3>
        <el-form-item label="用户名" prop="username" label-width="80px">
            <el-input type="input" auto-complete="off" placeholder="请输入用户名" v-model="formData.username"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password" label-width="80px">
            <el-input type="password" auto-complete="off" placeholder="请输入密码" v-model="formData.password"></el-input>
        </el-form-item>
        <el-form-item class="login-submit">
            <!--  这里通过@click绑定login函数,用于点击的时候触发登录功能 -->
            <el-button type="primary" class="login-submit" @click="login()">登录</el-button>
        </el-form-item>
    </el-form>
</template>

<script>
import { getCurrentInstance, reactive } from 'vue';
import { defineComponent } from 'vue-demi';
import { useRouter } from 'vue-router';
import { ElMessageBox } from 'element-plus';  //这是用来在账号密码错误时弹窗提示的
import store from '../../store/index.js';  //这里引入vuex,暂时先忽略,后面会介绍

export default defineComponent({
    setup() {
        const { proxy } = getCurrentInstance() // 注意这里,下面login函数会用到
        const router = useRouter()
        // vue3中获取表单数据需要使用reactive
        const formData = reactive({
            username: '',
            password: '',
        });
        // 使用异步的方式请求api
        let login = async () => {
            let res = await proxy.$api.login(formData) // 通过$api来调用login
            if (res.status === 200) {  // 如果返回码是200表明账号密码正确,校验通过
                // 下面两行代码是获取后端返回的access token和refresh token并存储起来,方便后面使用
                store.commit('setAccessToken', res.data.access)
                store.commit('setRefreshToken', res.data.refresh)
                store.commit('updateLastRefreshTime')  // 更新最近一次刷新access token的时间,用于比较access token是否过期,这里要和jwt的内容联系起来看
                router.push({ // 跳转到主页面,
                    name: 'main'
                })
            } else {
                // 如果账号密码错误的话就要进行提示,并且重新回到登录页面
                ElMessageBox.alert('账号密码错误,请重试!')
                router.push({
                    name: 'login'
                })
            }
        };
        return {
            formData,
            login,
        }
    }
})
</script>


<style lang="less" scoped>
.login-container {
    border-radius: 15px;
    background-clip: padding-box;
    margin: 180px auto;
    width: 350px;
    padding: 35px 35px 15px 35px;
    background-color: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
}
.login-title {
    margin: 0px auto 40px auto;
    text-align: center;
    color: #505458;
}
.login-submit {
    margin: 10px auto 0 auto;
    justify-content: center;
}
</style>

上面这一段代码实现了页面登录的样式和功能,但是我们还缺少一个指向这个页面的路由,现在来配置,修改src/router/index.js的内容,修改后如下,


import { createRouter, createWebHashHistory } from 'vue-router'

const routes = [
    {
        path: '/',
        name: 'main',
        redirect: '/home',
        component: () => import('../views/Main.vue'),
        children: [
            {
                path: '/home',
                name: 'home',
                component: () => import('../views/home/Home.vue'),
            },
            {
                path: '/other',
                name: 'other',
                component: () => import('../views/other/Other.vue'),
            },
        ]
    },
    {
        path: '/login',
        name: 'login',
        component: () => import('../views/login/Login.vue')
    }
]

const router = createRouter({
    history: createWebHashHistory(),
    routes
})

export default router

其实只修改了一个地方,就是在routes中添加了一个一级路由/login, 用于指向登录页面,这个应该也很好理解。
到这里登录页面相关的内容就完成了,但是整个登录功能还不能正常运行,还缺少一个重要部分,vuex。

通过vuex管理token(状态管理)

上一步在Login.vue这个文件中,我们先是引入了import store from '../../store/index.js' ,然后又是存储access token、refresh token和最后更新access token的时间,但是具体是怎么实现的没有介绍,现在来说一下。

vuex网上也是有很多,我贴两篇感觉写的还不错的博客:

  1. vuex-介绍
  2. vuex是什么

大家可以先浏览一下上面这两篇博客,对于vuex有一个整体的了解再继续看下面的内容。

假设大家已经看完了上了上面的两篇博客,我们开始介绍vuex在登录这个场景中应用。

在src/路径下创建store文件夹,然后在里面穿件index.js文件,文件内容如下,


import { createStore } from 'vuex'  // 引入createStore, 这里跟vue2不一样
import Cookies from "js-cookie"


export default createStore({
    state: {
        // state里面定义了一些要使用的变量
        access_token: '',
        refresh_token: '',
        last_token_refresh_time: new Date("October 01, 1975 00:00:00"),  // 以1975-10-01 00:00:00 为初始值
    },
    mutations: {
        // mutations里面主要是针对state里面的变量进行一些操作的函数,
        //  在登录这个场景中,分别对access token和refresh token有设置(set)、清除(clear)和获取(get)3个操作,一共6个
        // 额外还有一个更新access token的函数
        // access token 和 refresh token 我们是存储在cookie中,这个很简单,看代码就能理解了,想要深入了解的需要自行搜索
        setAccessToken(state, val) {
            state.access_token = val
            Cookies.set('access_token', val)
        },
        clearAccessToken(state) {
            state.access_token = ''
            Cookies.remove('access_token')
        },
        getAccessToken(state) {
            state.access_token = state.access_token || Cookies.get('access_token')
        },
        setRefreshToken(state, val) {
            state.refresh_token = val
            Cookies.set('refresh_token', val)
        },
        clearRefreshToken(state) {
            state.refresh_token = ''
            Cookies.remove('refresh_token')
        },
        getRefreshToken(state) {
            state.refresh_token = state.refresh_token || Cookies.get('refresh_token')
        },
        updateLastRefreshTime(state) {
            state.last_token_refresh_time = new Date().getTime()
            Cookies.set('last_token_refresh_time', state.last_token_refresh_time)
        },
    }
})

上面的代码展示了怎么样通过vuex来管理和操作token,但是配置好了之后应该怎么调用呢? 其实在Login.vue中已经使用过了,我在这里再解释一下。

  1. 首先要引入,可以看Login.vue里面import部分的最后一行,也就是 import store from '../../store/index.js';
  2. 通过store.commit(函数名,参数)的方法调用,比如 store.commit('setAccessToken', res.data.access)

好了,到这里基本就大功告成了,再项目的根目录下把项目运行起来,然后在浏览器中输入 http://localhost:5173/#/login 就会出现登录页面,账号和密码分别是admin和Pass1234,输入之后点击登录应该就能跳转到首页了。

记住在运行项目之前先安装依赖,执行cnpm install。

虽然到这里登录功能基本完成了,还是还缺一点。
大家有没有发现,到目前为止,虽然登录功能可以工作了,但是访问者依然可以在没有登录的情况下就访问所有的页面,也就是没有起到限制的作用,这个叫做路由守卫或者导航守卫,下面介绍。

路由守卫

路由守卫的内容上面介绍过了,实现起来其实比较简单,在main.js里面配置,main.js修改后内容如下,

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import router from './router/index.js'
import api from './api/api.js'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import './assets/main.css'
import store from './store/index.js'


const app = createApp(App)

for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
}

router.beforeEach((to, from, next) => {
    store.commit('getAccessToken')
    const token = store.state.access_token
    if (!token && to.name !== 'login') {
        next({ name: 'login' })
    } else if (token && to.name === 'login') {
        next({ name: 'home' })
    } else (
        next()
    )
})

app.use(router)
app.use(ElementPlus)
app.mount('#app')
app.config.globalProperties.$api = api

修改了两部分,

  1. 引入store
import store from './store/index.js'
  1. 配置路由守卫
router.beforeEach((to, from, next) => {
    store.commit('getAccessToken')
    const token = store.state.access_token
    if (!token && to.name !== 'login') {
        next({ name: 'login' })
    } else if (token && to.name === 'login') {
        next({ name: 'home' })
    } else (
        next()
    )
})

这一段代码的作用就是判断access_token是否存在,如果存在就放行,如果不存在就跳转到登录页面。
理解这一段代码的时候要结合Login.vue里面的login这个函数,这个函数在登录校验通过之后运行了 store.commit('setAccessToken', res.data.access) store.commit('setRefreshToken', res.data.refresh) ,这两行代码的作用就是更新(设置)access token 和refresh token,换句话说,登录成功之后,access token一定存在,如果access token不存在就可以认为没有登录或者没有登录成功,所以在路由守卫中可以利用access token来作为判断条件。

到这里,等个登录模块就完全做好了。

其实登录功能本身很简单,但是这个笔记里面讲到了vue3中api的管理,axios的封装,vuex的使用,所以会有点难。

思考题

最后留三个思考题:

  1. 现在的登录页面在输入账号密码之后一定要鼠标点击登录按钮才能登录,在输入框内按回车键是不行的,可以考虑一下怎么实现
  2. 加上登录模块之后,访问者一定要登录之后才能访问,但是也有的系统是允许匿名访问的,只有在做一些特定的操作的时候才需要登录,这个要怎么实现 ?
  3. 当前系统,所有访问者在登录之后能够访问的页面是一样的,但是项目中经常会需要根据访问者的权限不同开放不同页面,这个要怎么实现 ?

欢迎关注我的公众号
文章来源地址https://www.toymoban.com/news/detail-427660.html

到了这里,关于Vue3入门笔记----登录功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3 快速入门系列 —— 基础

    前面我们已经用 vue2 和 react 做过开发了。 从 vue2 升级到 vue3 成本较大,特别是较大的项目。所以许多公司对旧项目继续使用vue2,新项目则使用 vue3。 有些UI框架,比如ant design vue1.x 使用的 vue2。但现在 ant design vue4.x 都是基于 vue3,示例默认是 TypeScript。比如 table 组件管理。

    2024年04月08日
    浏览(43)
  • vue3 快速入门系列 —— 组件通信

    组件通信在开发中非常重要,通信就是你给我一点东西,我给你一点东西。 本篇将分析 vue3 中组件间的通信方式。 Tip :下文提到的绝大多数通信方式在 vue2 中都有,但是在写法上有一些差异。 在 vue3 基础上进行。 新建三个组件:爷爷、父亲、孩子A、孩子B,在主页 Home.vu

    2024年04月17日
    浏览(64)
  • vue3 快速入门系列 —— 其他API

    其他章节请看: vue3 快速入门 系列 前面我们已经学习了 vue3 的一些基础知识,本篇将继续讲解一些常用的 其他api ,以及较完整的分析vue2 和 vue3 的改变。 shallowRef shallow 中文:“浅层的” shallowRef:浅的 ref()。 先用 ref 写个例子: 这4个按钮都会触发页面数据的变化。 现在将

    2024年04月22日
    浏览(42)
  • Vue项目实战——【基于 Vue3.x + Vant UI】实现一个多功能记账本(登录注册页面,验证码)

    系列内容 参考链接 基于 Vue3.x + Vant UI 的多功能记账本(一) 项目演示,涉及知识点 基于 Vue3.x + Vant UI 的多功能记账本(二) 搭建开发环境 基于 Vue3.x + Vant UI 的多功能记账本(三) 开发导航栏及公共部分 项目演示 Vue3 + Vant UI_多功能记账本 1、登录注册页面 页面设计,页面

    2024年02月03日
    浏览(72)
  • 基于VUE3+Layui从头搭建通用后台管理系统(前端篇)二:登录界面及对应功能实现

      本章介绍系统登录界面、登录流程、登录接口等相关内容的开发,实现包括账号密码登录、短信验证登录等不同的登录方式,使用svg-capter生成图形验证码,使用expressjwt实现登录token的生成及验证。 1. 详细课程地址: https://edu.csdn.net/course/detail/38183 2. 源码下载地址: 点击

    2024年02月11日
    浏览(65)
  • vue3 快速入门系列 —— 状态管理 pinia

    其他章节请看: vue3 快速入门 系列 vue3 状态管理这里选择 pinia。 虽然 vuex4 已支持 Vue 3 的 Composition API,但是 vue3 官网推荐新的应用使用 pinia —— vue3 pinia redux、mobx、vuex、pinia都是集中式状态管理工具。与之对应的就是分布式。 Pinia 符合直觉 的 Vue.js 状态管理库 甚至让你忘

    2024年04月26日
    浏览(36)
  • Vue系列第五篇:Vue2(Element UI) + Go(gin框架) + nginx开发登录页面及其校验登录功能

       本篇使用Vue2开发前端,Go语言开发服务端,使用nginx代理部署实现登录页面及其校验功能。 目录 1.部署结构 2.Vue2前端 2.1代码结构 2.1源码 3.Go后台服务 3.2代码结构 3.2 源码 3.3单测效果 4.nginx 5.运行效果 6.问题总结   index.html !DOCTYPE html html   head     meta charset=\\\"utf-8\\\"     m

    2024年02月15日
    浏览(58)
  • vue3 - 最新手机扫码PC网站二维码登录功能,用手机端扫描PC端vue3网页的登录二维码,然后在手机上点击“确认登录“完成登录,PC网页生成登录二维码,用户拿手机扫码,手机上点确定后电脑端做出响应

    在vue3开发中,详细实现 “PC电脑网站生成微信登录二维码+手机扫码登录+双端同步数据”,利用扫码实现网站登录功能、用户用手机扫描电脑端二维码进行登录的详细教程步骤(电脑端PC网页、手机端都是vue3开发,支持将手机端改造成微信小程序、uniapp安卓苹果app、H5网页等

    2024年04月13日
    浏览(41)
  • Vue3 Flask 渐进式入门笔记

    以下均在Windows 10环境下实现。 安装node.js的过程略过。 1、在cmd命令行中执行以下命令: 2、查看vue版本 注意,如果电脑中以前有vue2版本,则需要卸载后重启电脑再重新安装,否则有可能安装失败。 1、执行以下命令以创建项目 第一步需要填写项目名称;后面的除router建议选

    2024年02月09日
    浏览(42)
  • vue3使用el-form实现登录、注册功能,且进行表单验证(Element Plus中的el-form)

    简介:Element Plus 中的 el-form 是一个表单组件,用于快速构建表单并进行数据校验。它提供了丰富的表单元素和验证规则,使表单开发变得更加简单和高效。可以搭配el-dialog实现当前页面的登录、注册页 ,这两天在vue3中用到了表单登录,特意记录一下,这里没有封装,直接使

    2024年02月07日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包