Vue3+Vant开发:登录功能
🙈作者简介:练习时长两年半的Java up主
🙉个人主页:程序员老茶
🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎
📚系列专栏:Java全栈,计算机系列(火速更新中)
💭 格言:种一棵树最好的时间是十年前,其次是现在
🏡动动小手,点个关注不迷路,感谢宝子们一键三连
目录
- 课程名:Vue 3
- 内容/作用:知识点/设计/实验/作业/练习
- 学习:Vue3+Vant开发:登录功能
- 1、创建登录路由
- 2、实现登录布局结构
- 3、登录布局实现
- 4、实现基本登录功能
- 5、登录状态提示
- 6、表单验证功能
- 7、处理用户Token
- 8、封装本地存储操作
- 总结
课程名:Vue 3
内容/作用:知识点/设计/实验/作业/练习
学习:Vue3+Vant开发:登录功能
1、创建登录路由
npm install vue-router@4
以上安装了最新版本的vue-router
.
下面在src
目录下面创建router
目录,在该目录下面创建index.js
文件,在该文件中完成路由的配置。
index.js
文件中代码如下所示:()
在下面的代码中,首先从vue-router
中导入createRouter
以及createWebHashHistory
.
createRouter
用来创建路由实例
createWebHashHistory
创建hash
路由
Layout
组件用来完成整个后台管理页面的布局。
在routes
数组中,定义了相应的路由规则
import { createRouter, createWebHashHistory } from "vue-router";
const routes = [{path: "/login",name: "login",component: () => import("../views/login/index.vue"),},
];
//创建路由实例
const router = createRouter({//history模式:createWebHistoryhistory: createWebHashHistory(), //使用hash模式routes,
});
export default router;
下面在src
目录下面创建views
目录,在该目录下面创建login
目录,然后在创建index.vue
.
该组件中的内容如下所示:
<template><div>登录</div>
</template><script>
export default {};
</script><style></style>
下面,返回到main.js
文件中使用创建好的路由对象
import { createApp } from "vue";
import App from "./App.vue";
import Vant from "vant";
import "vant/lib/index.css";
import "amfe-flexible";
import router from "./router"; //导入路由对象
createApp(App).use(Vant).use(router).mount("#app"); //使用路由
同时在App.vue
文件中,添加router-view
,指定路由的出口。
<template><router-view></router-view>
</template><script setup></script><style></style>
在浏览器中输入http://localhost:3000/#/login
查看效果。
2、实现登录布局结构
<template><div class="login-container"><!-- 导航栏 --><van-nav-bar title="登录" /><!-- 导航栏结束 --><!-- 登录表单 --><van-form><van-field name="userName" placeholder="请输入用户名" /><van-field name="userPwd" placeholder="请输入密码" /><div style="margin: 16px"><van-button block type="primary" native-type="submit">提交</van-button></div></van-form><!-- 登录表单结束 --></div>
</template><script>
export default {};
</script><style></style>
3、登录布局实现
这里我们首先设置一下,导航栏的样式。由于很多页面都会用到导航栏,所以可以将样式定义在全局的文件中,而不是单独的定义在登录组件中。
在src
目录下面创建styles
目录,在该目录下面创建index.css
文件,该文件中的代码如下所示:
.page-nav-bar {background-color: #3296fa;
}
.page-nav-bar .van-nav-bar__title {/* 这里的van-nav-bar__title,可以查看原有的导航栏的样式*/color: #fff;
}
在登录组件的导航栏中使用该样式。(在main.js
文件中导入import "./styles/index.css";
)
<van-nav-bar title="登录" class="page-nav-bar" />
下面给登录表单的文本框与密码框添加对应的图标。
对应的官网:
https://vant-contrib.gitee.io/vant/v3/#/zh-CN/field
<van-form><van-field name="userName" placeholder="请输入用户名" left-icon="manager" /><van-field name="userPwd" placeholder="请输入密码" left-icon="lock"/></van-field><div style="margin: 16px"><van-button block type="primary" native-type="submit"> 提交</van-button></div></van-form>
这里给手机号与验证码添加了left-icon
设置了图标。同时设置了“发送验证码”的按钮
4、实现基本登录功能
注意:这里只是实现基本登录效果,把服务端返回的内容打印出来,不涉及到登录状态的提示与登录状态的存储操作。
首先在src
目录下面创建api
目录,在该目录下面创建user.js
文件,该文件中封装了用户请求的相关处理模块。
// 封装用户相关的请求模块
import request from "../utils/request";
export const login = (data) => {return request({method: "POST",url: "/user/login",data,});
};
下面修改login.vue
组件中的内容
<div class="login-container"><!-- 导航栏 --><van-nav-bar title="登录" class="page-nav-bar" /><!-- 导航栏结束 --><!-- 登录表单 --><van-form @submit="onSubmit"><van-fieldname="userName"placeholder="请输入用户名"v-model="userName"left-icon="manager":rules="userFormRules.userName"/><van-fieldname="userPwd"placeholder="请输入密码"v-model="userPwd"left-icon="lock":rules="userFormRules.userPwd"></van-field><div style="margin: 16px"><van-button block type="primary" native-type="submit">登录</van-button></div></van-form><!-- 登录表单结束 --></div>
给每个van-field
绑定了v-model
,同时给van-form
添加了@submit
事件。
<script>
import { reactive, toRefs } from "vue";
import { login } from "../../api/user"; //导入login方法,进行请求的发送function useSubmit(user) {
const onSubmit = async () => {//1、获取表单数据//2、表单验证//3、提交表单请求Toast.loading({message: "登录中...",forbidClick: true, //禁用背景点击duration: 0, //持续时间,默认是2000毫秒,如果为0则持续展示});const res = await login(user);if (res.data.code === 0) {store.commit("setUser", res.data);Toast.success("用户登录成功");} else {Toast.fail("用户名或密码错误");}//4、根据请求响应结果处理后续操作。};return {onSubmit,};
}
export default {setup() {const user = reactive({userName: "", //用户名userPwd: "", //用户密码});return {...toRefs(user),...useSubmit(user),};},
};
</script>
在setup
方法中,定义user
响应式对象,最后返回。同时将外部定义的useSubmit
方法进行调用。
5、登录状态提示
const onSubmit = async () => {//1、获取表单数据//2、表单验证//3、提交表单请求Toast.loading({message: "登录中...",forbidClick: true, //禁用背景点击duration: 0, //持续时间,默认是2000毫秒,如果为0则持续展示});const res = await login(user);if (res.data.code === 0) {store.commit("setUser", res.data);Toast.success("用户登录成功");} else {Toast.fail("用户名或密码错误");}//4、根据请求响应结果处理后续操作。};return {onSubmit,};
}
这里使用了Toast
组件,同时需要进行导入:
import { Toast } from "vant";
由于网络比较快,可能看不到登录中...
这个提示,所以可以把网络设置慢一些。
可以修改NetWork
中的No throttling
中的Slow 3G
6、表单验证功能
在setup
函数中定义校验规则,并且将其返回。
setup() {const user = reactive({userName: "", //用户名userPwd: "", //用户密码});//定义校验规则const userFormRules = {userName: [{ required: true, message: "请填写用户名" }],userPwd: [{required: true,message: "请填写密码",},{pattern: /^\d{6}$/,message: "密码格式错误",},],};return {...toRefs(user),...useSubmit(user),userFormRules, //返回校验规则};},
在表单中使用校验规则:
<van-fieldname="userName"placeholder="请输入用户名"v-model="userName"left-icon="manager":rules="userFormRules.userName"/><van-fieldname="userPwd"placeholder="请输入密码"v-model="userPwd"left-icon="lock":rules="userFormRules.userPwd"></van-field>
7、处理用户Token
用户登录成功以后,会返回token
数据。
Token
是用户登录成功之后服务端返回的一个身份令牌,在项目中经常要使用。
例如:访问需要授权的API
接口。
校验页面的访问权限等。
同时,这里我们还需要将token
数据进行存储,这样在访问其它的页面组件的时候,就可以获取token
数据来进行校验。
关于token
数据存储在哪儿呢?
可以存储到本地:
存储到本地的问题是,数据不是响应式的。
存储到Vuex
中,获取方便,并且是响应式的。但是存储到Vuex
中也是有一定的问题的,就是当我们刷新浏览器的时候,数据就会丢失,所以还是需要把token
数据存放到本地,存储到本地的目的就是为了进行持久化。
所以这里我们需要在登录成功以后,把token
数据存储到vuex
中,这样可以实现响应式,在本地存储就是为了解决持久化的问题。
安装最新版本的Vuex
npm install vuex@next --save
下面在src
目录下面创建store
目录,在store
目录中index.js
文件,该文件中的代码如下所示:
import { createStore } from "vuex";
const store = createStore({state: {//存储当前登录用户信息,包含token等数据user: null,},mutations: {setUser(state, data) {state.user = data;},},
});
export default store;
在上面的代码中,创建了store
容器,同时指定了state
对象,在该对象中定义user
属性存储登录用户信息。
在mutations
中定义setUser
方法,完成用户信息的更新。
下面,要实现的就是,当登录成功以后,更新user
这个状态属性。
当然,这里首先要做的就是把store
注入到Vue
的实例中。
import { createApp } from "vue";
import App from "./App.vue";
import Vant from "vant";
import "vant/lib/index.css";
import "amfe-flexible";
import "./styles/index.css";
import router from "./router";
import store from "./store"; //导入store
createApp(App).use(Vant).use(router).use(store).mount("#app"); //完成store的注册操作
在main.js
文件中,我们导入了store
,并且注册到了Vue
实例中。
下面返回到views/login/index.vue
页面中,把登录的信息存储到store
容器中。
import { reactive, toRefs, ref } from "vue";
import { login, sendSms } from "../../api/user";
import { Toast } from "vant";
import { useStore } from "vuex"; //导入useStore
在上面的代码中导入useStore
.
export default {setup() {const loginForm = ref();//获取storeconst store = useStore();
在setup
函数中,调用useStore
方法,获取store
容器。
return {...toRefs(user),...useSubmit(user, store),//在调用useSubmit方法的时候传递store容器userFormRules,loginForm,};
//用户登录
function useSubmit(user, store) {const onSubmit = async () => {//1、获取表单数据//2、表单验证//3、提交表单请求Toast.loading({message: "登录中...",forbidClick: true, //禁用背景点击duration: 0, //持续时间,默认是2000毫秒,如果为0则持续展示});const res = await login(user);if (res.data.code === 0) {store.commit("setUser", res.data);Toast.success("用户登录成功");} else {Toast.fail("用户名或密码错误");}//4、根据请求响应结果处理后续操作。};return {onSubmit,};
}
登录成功以后,获取到返回的数据,同时调用store
中的commit
方法完成数据
的保存
现在,我们虽然把登录成功的数据,存储到Vuex
中,但是当我们刷新浏览器的时候,Vuex
中的数据还是会丢失的。所以这里,我们还需要将其存储到本地中。
下面修改一下store/index.js
文件中的代码:
import { createStore } from "vuex";
const TOKEN_KEY = "TOUTIAO_USER";
const store = createStore({state: {//存储当前登录用户信息,包含token等数据// user: null,user: JSON.parse(window.localStorage.getItem(TOKEN_KEY)),},mutations: {setUser(state, data) {state.user = data;window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user));},},
});
export default store;
在mutations
中的setUser
方法中,将登录成功的用户数据存储到了localStorage
中,在存储的时候,将数据转成了字符串。
同时在state
中获取数据的时候,就从localStorage
中获取,当然获取的时候,再将其转换成对象的形式。
下面,我们可以在App.vue
中做一下测试:
<template><div><router-view></router-view></div>
</template><script>
import { useStore } from "vuex";
export default {setup() {const store = useStore();console.log(store.state.user);},
};
</script><style></style>
通过查看浏览器的控制台,可以查看到对应的登录用户的token
数据
8、封装本地存储操作
在我们的项目中,有很多的地方都需要获取本地存储的数据,如果每次都写:
JSON.parse(window.localStorage.getItem(TOKEN_KEY)),
window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user));
就比较麻烦了。所以这里我们建议把操作本地数据单独的封装到一个模块中。
在utils
目录下面创建storage.js
文件,该文件中的代码如下所示:
// 存储数据
export const setItem = (key, value) => {//将数组,对象类型的数据转换为JSON格式的字符串进行存储if (typeof value === "object") {value = JSON.stringify(value);}window.localStorage.setItem(key, value);
};
//获取数据
export const getItem = (key) => {const data = window.localStorage.getItem(key);//这里使用try..catch的,而不是通过if判断一下是否为json格式的字符串,然后在通过parse进行转换呢,目的就是是为了方便处理,因为对字符串进行判断看一下是否为json格式的字符串,比较麻烦一些。还需要通过正则表达式来完成。而通过try..catch比较方便// 如果data不是一个有效的json格式字符串,JSON.parse就会出错。try {return JSON.parse(data);} catch (e) {return data;}
};
//删除数据
export const removeItem = (key) => {window.localStorage.removeItem(key);
下面返回到store/index.js
文件中,修改对应的代码,这里使用我们上面封装好的代码。
import { createStore } from "vuex";
import { getItem, setItem } from "../utils/storage";
const TOKEN_KEY = "TOUTIAO_USER";
const store = createStore({state: {//存储当前登录用户信息,包含token等数据// user: null,// user: JSON.parse(window.localStorage.getItem(TOKEN_KEY)),user: getItem(TOKEN_KEY),},mutations: {setUser(state, data) {state.user = data;setItem(TOKEN_KEY, state.user);// window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user));},},
});
export default store;
在上面的代码中,我们导入getItem
和setItem
两个方法,然后在存储登录用户信息,和获取登录用户信息的时候,直接使用这两个方法,这样就非常简单了。
下面返回浏览器进行测试。
把以前localStorage
中存储的内容删除掉。
然后重新输入用户名和密码,发现对应的localStorage
中存储了对应的数据。
总结
感谢小伙伴们一键三连,咱们下期文章再见~
往期专栏 |
---|
Java全栈开发 |
数据结构与算法 |
计算机组成原理 |
操作系统 |
数据库系统 |
物联网控制原理与技术 |
相关文章:

Vue3+Vant开发:登录功能
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…...

Linux程序调试优化(1)——内存占用详解及优化思路
文章目录 1.free查看总体的内存占用2./proc/$PID/status 查看某进程状态 linux开发最重要的两个参数,分别是内存以及CPU使用率,若内存出现严重不足,则在需要使用内存时,可能出现申请不到的情况,导致 OOM,L…...

高效解决Visual Studio Code中文乱码问题
文章目录 问题解决步骤 问题 Visual Studio Code新建一个文件编码方式总是默认GBK,如果我不修改成默认UTF-8,那么每次运行,如果有中文需要输出就会乱码! 解决步骤 之后我会持续更新,如果喜欢我的文章,请记…...

springboot接口提高查询速度方法
接口想要提高查询速度,需要减少查询数据库的次数,需要把循环里面的查询提出来一次性查询完毕,然后通过java代码来获取响应的值。如下所示: List<OrderInfoHtVO> orderInfoList orderInfoService.getOrderInfoHtlist(query…...

如何在苹果手机上安装iOS应用的.ipa文件?
哈喽,大家好呀,淼淼又来和大家见面啦,如今移动应用市场不断的发展,许多开发者小伙伴们都选择将他们的应用发布到苹果App Store上,但是,有时候他们可能希望通过直接分享IPA文件来分发他们的App,那…...

IDEA pom.xml显示灰色并被划线
在使用 IDEA 进行开发的过程中,有时候会遇到 pom.xml 显示灰色并被划线的情况,如下图: 这一般是因为该文件被 Maven 忽略导致的,可以进行如下操作恢复: 设置保存后,可以看到 pom.xml 恢复了正常:…...

玄子Share-使用 Pycharm 执行 Shell 脚本
玄子Share-使用 Pycharm 执行 Shell 脚本 Why? 为什么我要使用 Pycharm 执行 Shell 脚本呢,我直接使用 Linux 不行吗? 使用 Pycharm 执行 Shell 脚本的好处 我们的宿主机都是 WIndows 平台,若想编译 Shell 脚本,我…...

如何让Nrf connect、EFR connect直接显示特征值数据及其单位
效果如图:app直接显示了我的温度,并且有两位小数,还有温度单位。这是怎么做到的呢? 这次我们仍以TLS8258为例,当然如果是其他蓝牙芯片,配置方式也是大差不差,规则一样的。 #define GATT_CHARA…...

python笔记
Vim 修改文件格式 unix|dos vim fileName :set ff //显示出文件格式类型 :set ffunix //设置成unix格式 :set ffdos //windows文件格式python *和**的区别 将可变关键字打包成不可变的元组 def func(*args): print(args) func(1, 2, 3) # 输出:(1, 2, 3)…...

Java编译期注解处理器AbstractProcessor使用
我们接触的注解主要分为以下两类 运行时注解:通过反射在运行时动态处理注解的逻辑编译时注解:通过注解处理器在编译期动态处理相关逻辑 编译期注解我们常用的有Lombok,在class文件中自动生成get和set方法 解编译期处理流程最关键的一个类就…...

JetBrains相关的IDE有哪些?
JetBrains是一家成立于2002年的捷克软件开发公司,总部位于捷克的布拉格,同时在俄罗斯的圣彼得堡及美国麻州波士顿等地设有办公室。该公司以其高质量的集成开发环境(IDE)产品而闻名,这些产品被广泛应用于各种编程语言和…...

Git-常规用法-含解决分支版本冲突解决方法
目录 前置条件 已经创建了Gitee账号 创建一个远程仓库 Git的优点 版本控制 Git 下载 Git的使用 检查Git的是否安装成功 git的常用命令 常用流程 Git 分支 分支流程 Git 远程仓库 远程仓库流程 特殊 可能遇到的问题 前置条件 已经创建了Gitee账号 创建一个远程仓…...

基于springboot实现大型商场应急预案管理系统项目【项目源码+论文说明】
基于SpringBoot实现大型商场应急预案管理系统演示 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了大型商场应急预案管理系统的开发全过程。通过分析大型商场应急预案管理系统管理的不足,创建了一个…...

系统学c#:1、基础准备(软件下载与安装)
一、Vs软件下载与安装 访问Visual Studio官方网站: https://visualstudio.microsoft.com/zh-hans/downloads 下载Visual Studio 运行exe文件,点击“继续” 初始文件安装完成后选择我们需要安装的项,并勾选好必要的单个组件,设…...

解决CSS中鼠标移入到某个元素其子元素被遮挡的问题
我们在开发中经常遇到一种场景,就是给元素加提示信息,就是鼠标移入到盒子上面时,会出现提示信息这一功能,如果我们给盒子加了hover,当鼠标移入到盒子上时,让他往上移动5px,即transform: transla…...

【华为OD机试】虚拟理财游戏【C卷|100分】
【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。 现有一家Bank,它提供有若干理财产品 m 个,风险及投资回报不同,你有 N(元)进行投资,能接收的总风险…...

ssh 使用
ssh 使用 一、ssh 安装二、ssh 使用1. ssh 登录2. ssh-keygen 免密登录(1) ssh 生成密钥(2) 开启远程主机的密钥登陆(3) ssh 分发公钥 3. ssh-copy-id 复制公钥到远程主机4. scp 复制 系统环境: linux(ubuntu,debian,kali) 一、ssh 安装 sudo apt update sudo apt install op…...

Springboot+Vue项目-基于Java+MySQL的母婴商城系统(附源码+演示视频+LW)
大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &…...

Android多线程:Handler runOnUiThread 异步消息处理机制
目录 一,Android中的多线程问题 1.模拟耗时工作 2.Android开启子线程 二,在子线程中更新UI 1.异步消息处理机制 Handler 2.使用runOnUiThread更新UI 一,Android中的多线程问题 Android用户界面是与用户交互的接口,对于用户的…...

AndroidStudio 导出aar包,并使用
打包 1、确认当前选项是否勾选,如未勾选请先勾选。 2、勾选完成后重启Android Studio。 3、重启完成后,选中要打包的module 4、打包完成 使用 1.在项目中新建libs,放入aar文件。 2.修改配置 添加如下代码 flatDir {dirs("libs")}3.修改app…...

python与设计模式之工厂模式的那些事儿
一、工厂模式 工厂模式实现了按需创建的最佳模式,其目的是为了隐藏创建类的细节与过程,通过一个统一的接口来创建所需的对象。 话说没了皇位争夺权的皇三接到了一个外征的工作,始皇给了5个亿的经费让皇三组建一个军队。打权总是要进行武器采…...

什么是区块链?
简介 作者在学习虚拟机时突然发现有人提出如何在区块链开发一款轻量型jvm,由于对区块链不太了解,也不理解区块链为什么需要轻量型jvm。恰好最近有空,泡在图书馆找了本书《区块链导论》对相关知识进行了学习。 区块链系统; 特点…...

2022年电赛F题23年电赛D题-信号调制度测量装置说明中提到带通采样定律。
2022年电赛F题-信号调制度测量装置说明中提到带通采样定律。 23年电赛D题十分相似,但是22年载波达到了10M,根据奈奎斯特采样定理,我们知道想要分析出频谱不混叠的频谱图,采样率必须大于最大谐波的二倍。那么就意味着AD采样率要大…...

Rust面试宝典第2题:逆序输出整数
题目 写一个方法,将一个整数逆序打印输出到控制台。注意:当输入的数字含有结尾的0时,输出不应带有前导的0。比如:123的逆序输出为321,8600的逆序输出为68,-609的逆序输出为-906。 解析 这道题本身并没有什么…...

Linux笔记之查看docker容器目录映射
Linux笔记之查看docker容器目录映射 —— 2024-04-15 code review! docker inspect 容器ID或容器名 | grep -A 20 Mounts实践 grep -A 参数详解: grep 的 -A 参数用于在输出中包括匹配行后的指定数目的行。 使用 -A 参数 该参数的基本语法如下: …...

网络编程探索系列之——广播原理剖析
hello !大家好呀! 欢迎大家来到我的网络编程系列之广播原理剖析,在这篇文章中, 你将会学习到如何在网络编程中利用广播来与局域网内加入某个特定广播组的主机! 希望这篇文章能对你有所帮助,大家要是觉得我写…...

jar包解压和重新打包
1、Windows系统上解压和重新打包jar包的命令: (1). 解压jar包: jar -xf yourJarFile.jar (2). 重新打包jar包: jar -cf newJarFile.jar * 2、Linux系统上解压和重新打包jar包的命令: (1). 解压jar包: unzip your…...

Python基于Django的微博热搜、微博舆论可视化系统
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...

Flink SQL:debezium-json 格式的表一定是数据库的 CDC 数据吗?
debezium-json 格式有一种非常典型的应用场景,就是:上游(Source)是一张使用 Flink CDC 接入的关系数据库中的表,下游(Sink)是一张创建在 Kafka 上的表,这张表的 format 往往会定义为 debezium-json,以便 Flink 能获得全面的 CDC 信息用于流上的实时处理,这种场景我们…...

基于STM32的RFID智能门锁系统
本文针对RFID技术,着重研究了基于单片机的智能门锁系统设计。首先,通过链接4*4按键模块与主控STM32,实现了多种模式,包括刷卡开锁、卡号权限管理、密码开锁、修改密码、显示实时时间等功能。其次,采用RC522模块与主控S…...