Vue3项目练习详细步骤(第五部分:用户模块的功能)

顶部导航栏个人信息显示

接口文档

接口请求与绑定 

导航栏下拉菜单功能

路由实现

退出登录和路由跳转实现

基本资料修改

页面结构

 接口文档

 接口请求与绑定 

修改头像

页面结构 

头像回显

头像上传

 接口文档

重置密码

页面结构

接口文档

接口请求与绑定

 

顶部导航栏个人信息显示

        在Layout.vue中,页面加载完就发送请求,获取个人信息展示,并存储到pinia中,因为将来在个人中心中修改信息的时候还需要使用 。

 接口文档

接口请求与绑定 

在stores目录下新建userInfo.js并定义Store用于将数据存储到pinia中

import { defineStore } from "pinia"
import {ref} from 'vue'export const useUserInfoStore = defineStore('userInfo',()=>{//1.定义用户信息const info = ref({})//2.定义修改用户信息的方法const setInfo = (newInfo)=>{info.value = newInfo}//3.定义清空用户信息的方法const removeInfo = ()=>{info.value={}}return{info,setInfo,removeInfo}
},{persist:true
})

在user.js中提供获取个人信息的函数

//获取个人信息
export const userInfoGetService = ()=>{return request.get('/user/userInfo');
}

 在Layout.vue中获取个人信息,并存储到pinia中

//导入接口函数
import {userInfoGetService} from '@/api/user.js'
//导入pinia
import {useUserInfoStore} from '@/stores/userInfo.js'
const userInfoStore = useUserInfoStore();
import {ref} from 'vue'//获取个人信息
const getUserInf = async ()=>{let result = await userInfoGetService();if(result.code === 0){//成功//存储piniauserInfoStore.info =result.data;}else{//失败alert('获取信息失败')}
}getUserInf()

 Layout.vue的顶部导航栏中,绑定展示昵称和头像

<div>用户:<strong>{{ userInfoStore.info.nickname ? userInfoStore.info.nickname : userInfoStore.info.usrename }}</strong></div><el-avatar :src="userInfoStore.info.userPic ? userInfoStore.info.userPic : avatar" />

保存后刷新页面可以看到用户名称和头像正常显示 

 

导航栏下拉菜单功能

 在el-dropdown中有四个子条目

  • 基本资料
  • 更换头像
  • 重置密码
  • 退出登录

其中其三个起到路由功能,跟左侧菜单中【个人中心】下面的二级菜单是同样的功能,退出登录需要删除本地pinia中存储的token以及userInfo

路由实现

 在el-dropdown标签上绑定command事件,当有条目被点击后,会触发这个事件

<el-dropdown placement="bottom-end" @command="handleCommand">

在el-dropdown-item标签上添加command属性,属性值和路由表中/user/xxx保持一致

<el-dropdown-item command="info" :icon="User">基本资料</el-dropdown-item>
<el-dropdown-item command="avatar" :icon="Crop">更换头像</el-dropdown-item>
<el-dropdown-item command="password" :icon="EditPen">重置密码</el-dropdown-item>
<el-dropdown-item command="logout" :icon="SwitchButton">退出登录</el-dropdown-item>

退出登录和路由跳转实现

定义并编写handleCommand函数

import {useRouter} from 'vue-router'
const router = useRouter();
import {ElMessage,ElMessageBox} from 'element-plus'
import { useTokenStore } from '@/stores/token.js'
const tokenStore = useTokenStore()
const handleCommand = (command) => {if (command === 'logout') {//退出登录ElMessageBox.confirm('是否退出登录','提示',{confirmButtonText: '确认',cancelButtonText: '取消',type: 'warning',}).then(async () => {//用户点击了确认//清空pinia中的token和个人信息userInfoStore.info={}tokenStore.token=''//跳转到登录页router.push('/login')ElMessage.success('成功退出登录')}).catch(() => {//用户点击了取消ElMessage({type: 'info',message: '取消退出',})})} else {//路由router.push('/user/' + command)}
}

 保存后刷新既可以完成跳转和退出登录

 

基本资料修改

页面结构

在UserInfo.vue文件中完成用户资料修改的页面结构组件

<script setup>
import { ref } from 'vue'
const userInfo = ref({id: 0,username: 'zhangsan',nickname: 'zs',email: 'zs@163.com',
})
const rules = {nickname: [{ required: true, message: '请输入用户昵称', trigger: 'blur' },{pattern: /^\S{2,10}$/,message: '昵称必须是2-10位的非空字符串',trigger: 'blur'}],email: [{ required: true, message: '请输入用户邮箱', trigger: 'blur' },{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }]
}
</script>
<template><el-card class="page-container"><template #header><div class="header"><span>基本资料</span></div></template><el-row><el-col :span="12"><el-form :model="userInfo" :rules="rules" label-width="100px" size="large"><el-form-item label="登录名称"><el-input v-model="userInfo.username" disabled></el-input></el-form-item><el-form-item label="用户昵称" prop="nickname"><el-input v-model="userInfo.nickname"></el-input></el-form-item><el-form-item label="用户邮箱" prop="email"><el-input v-model="userInfo.email"></el-input></el-form-item><el-form-item><el-button type="primary">提交修改</el-button></el-form-item></el-form></el-col></el-row></el-card>
</template>

个人信息之前已经存储到了pinia中,只需要从pinia中获取个人信息,替换模板数据即可

import { ref } from 'vue'
//导入Store
import { useUserInfoStore } from '@/stores/userInfo.js';
const userInfoStore = useUserInfoStore()
//数据模型
const userInfo = ref({...userInfoStore.info}) //...用于展开可迭代对象 拆出其中的每个元素

 接口文档

 

 接口请求与绑定 

 在src/api/user.js中提供修改基本资料的函数

//修改个人信息
export const userInfoUpdateService = (userInfo)=>{return request.put('/user/update',userInfo)
}

在UserInfo.vue文件中提供updateUserInfo请求函数

//修改用户信息
import {userInfoUpdateService} from '@/api/user.js'
import { ElMessage } from 'element-plus';
const updateUserInfo = async ()=>{let result = await userInfoUpdateService(userInfo.value)ElMessage.success(result.message? result.message:'修改成功')//更新pinia中的数据userInfoStore.info.nickname=userInfo.value.nicknameuserInfoStore.info.email = userInfo.value.email
}

 给修改按钮绑定单击事件

<el-button type="primary" @click="updateUserInfo">提交修改</el-button>

 保存刷新后能正常完成用户信息的数据回显和更新

修改头像

页面结构 

在UserAvatar.vue文件中完成用户资料修改的页面结构组件

<script setup>
import { Plus, Upload } from '@element-plus/icons-vue'
import {ref} from 'vue'
import avatar from '@/assets/default.png'
const uploadRef = ref()//用户头像地址
const imgUrl= avatar</script><template><el-card class="page-container"><template #header><div class="header"><span>更换头像</span></div></template><el-row><el-col :span="12"><el-upload ref="uploadRef"class="avatar-uploader" :show-file-list="false"><img v-if="imgUrl" :src="imgUrl" class="avatar" /><img v-else src="avatar" width="278" /></el-upload><br /><el-button type="primary" :icon="Plus" size="large"  @click="uploadRef.$el.querySelector('input').click()">选择图片</el-button><el-button type="success" :icon="Upload" size="large">上传头像</el-button></el-col></el-row></el-card>
</template><style lang="scss" scoped>
.avatar-uploader {:deep() {.avatar {width: 278px;height: 278px;display: block;}.el-upload {border: 1px dashed var(--el-border-color);border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;transition: var(--el-transition-duration-fast);}.el-upload:hover {border-color: var(--el-color-primary);}.el-icon.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 278px;height: 278px;text-align: center;}}
}
</style>

头像回显

 从pinia中读取用户的头像数据

//读取用户信息
//导入Store
import {useUserInfoStore} from '@/stores/userInfo.js'
const userInfoStore = useUserInfoStore()
//用户头像地址
const imgUrl=ref(userInfoStore.info.userPic)

img标签上绑定图片地址(三元运输符判断)

<img v-if="imgUrl" :src="imgUrl" class="avatar" />
<img v-else :src="avatar" width="278" />

 保存刷新查看头像回显

 

头像上传

  • action: 服务器接口路径
  • headers: 设置请求头,需要携带token
  • on-success: 上传成功的回调函数
  • name: 上传图片的字段名称

 为el-upload指定属性值

                <el-upload ref="uploadRef"class="avatar-uploader" :show-file-list="false":auto-upload="true"action="/api/upload"name="'file'":headers="{'Authorization':tokenStore.token}":on-success="uploadSuccess">

 提供上传成功的回调函数

//导入tokenStore
import {useTokenStore} from '@/stores/token.js'const tokenStore = useTokenStore();
//头像上传成功回调函数
const uploadSuccess = (result)=>{//回显图片imgUrl.value = result.data
}

 接口文档

 接口请求与绑定

在user.js中提供修改头像的函数

//修改头像
export const userAvatarUpdateService=(avatarUrl)=>{let params = new URLSearchParams();params.append('avatarUrl',avatarUrl)return request.patch('/user/updateAvatar',params)
}

在UserAvatar.vue文件中提供updateAvatar函数,完成头像更新  

//调用接口,更新头像url
import {userAvatarUpdateService} from '@/api/user.js'
//导入Element-Plus提示框组件
import {ElMessage} from 'element-plus'
const updateAvatar = async ()=>{let result = await userAvatarUpdateService(imgUrl.value)if(result.code === 0){//成功ElMessage.success(result.message? result.message:'修改成功')//更新pinia中的数据userInfoStore.info.userPic=imgUrl.value}else{ElMessage.error('修改失败')}}

 在【上传头像】按钮绑定单击事件

<el-button type="success" :icon="Upload" size="large" @click="updateAvatar">
上传头像
</el-button>

如果是用的网络存储服务器那么到这一步修改头像就完成了!

练习项目后端使用的是本地文件存储,所以没有用到网络url,传入本地文件地址后端会报如下错误

 

点击上传由于这里练习项目没有网络服务器 数据是上传到本地的所以浏览器会拦截本地文件加载导致不能造成数据回显,但是目录下是有图片成功上传到的。

后续继续完成项目建议修改src中的值为模拟的固定网络图片url地址:https://ts1.cn.mm.bing.net/th/id/R-C.4bdc8f7f0e0201905fe400fb5156b7c7?rik=MVFo1SU7cYgFqg&riu=http%3A%2F%2Fwww.spasvo.com%2Fckfinder%2Fuserfiles%2Fimages%2F2020061536450116.jpg&ehk=r7Pp%2FX3wIOhP%2FcuW0ITLAHeD0sZPNatsyfpC3XWOM0s%3D&risl=&pid=ImgRaw&r=0

  如果自己有网络服务器可以使用网络服务器的图片url

 

重置密码

页面结构

在UserResetPassword.vue文件中完成重置密码的页面的结构组件 

<script setup>
import { ref } from 'vue'
const password = ref({
"old_pwd":"",
"new_pwd":"",
"re_pwd":""
})
const rules = {oldPassword: [{ required: true, message: '请输入原密码', trigger: 'blur' },{pattern: /^\S{5,12}$/,message: '密码必须是5-12位的非空字符串',trigger: 'blur'}],newPassword: [{ required: true, message: '请输入新密码', trigger: 'blur' },{pattern: /^\S{5,12}$/,message: '密码必须是5-12位的非空字符串',trigger: 'blur'}],rePassword: [{ required: true, message: '请输入确认新密码', trigger: 'blur' },{pattern: /^\S{5,12}$/,message: '密码必须是5-12位的非空字符串',trigger: 'blur'}]}
</script>
<template><el-card class="page-container"><template #header><div class="header"><span>重置密码</span></div></template><el-row><el-col :span="12"><el-form :model="password" :rules="rules" label-width="100px" size="large"><el-form-item label="原密码" prop="oldPassword"><el-input type="password" placeholder="请输入原密码" show-password v-model="password.old_pwd"></el-input></el-form-item><el-form-item label="新密码" prop="newPassword"><el-input type="password" placeholder="请输入新密码" show-password v-model="password.new_pwd"></el-input></el-form-item><el-form-item label="确认新密码" prop="rePassword"><el-input type="password" placeholder="请输入确认密码" show-password v-model="password.re_pwd"></el-input></el-form-item><el-form-item><el-button type="primary">修改密码</el-button><el-button type="primary">重置</el-button></el-form-item></el-form></el-col></el-row></el-card>
</template>

 定义清空数据模型的函数

在重置按钮处绑定清空文本框数据的单击事件

<el-button type="primary" @click="clearData()">重置</el-button>

接口文档

接口请求与绑定

  在src/api/user.js中提供重置密码的函数

//重置密码
export const userPasswordUpdateService = (password) => {return request.patch('/user/updatePwd',password)
}

 在UserResetPassword.vue文件中提供userPasswordUpdate请求函数

//导入路由
import {useRouter} from 'vue-router'
const router = useRouter();
//导入element提示框组件
import { ElMessage,ElMessageBox } from 'element-plus';
//导入userPasswordUpdateService函数
import {userPasswordUpdateService} from '@/api/user.js'const userPasswordUpdate = async() => {ElMessageBox.confirm('确认是否重置密码,重置之后将退出登录','提示',{confirmButtonText: '确认',cancelButtonText: '取消',type: 'warning',}).then(async () => {//用户点击了确认let result = userPasswordUpdateService(password.value)if(result.code ===0){//成功//跳转到登录页router.push('/login')ElMessage.success(result.message?result.message:'重置成功')ElMessage.success('退出登录')}else{ElMessage.error('操作失败')}}).catch(() => {//用户点击了取消ElMessage({type: 'info',message: '取消重置',})})
}

 在修改密码按钮处绑定该函数单击事件

<el-button type="primary" @click="userPasswordUpdate()">修改密码</el-button>

 保存后查看效果

项目练习完结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/20048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自然语言处理学习路线

学习目标 NLP 系统知识&#xff08;从入门到入土&#xff09; 学习内容 NLP的基本流程&#xff1a;&#xff08;待更&#xff09;文本预处理&#xff08;标点符号处理、繁体转简体、分词Tokenizer&#xff09;&#xff1a;&#xff08;待更&#xff09;词袋模型&#xff08;TF…

红外热成像观驱一体仪,夜间驱鸟新利器

夜间驱鸟是机场鸟防工作的重点和难点&#xff0c;但红外热成像观驱一体仪的出现解决了这个问题&#xff0c;它结合了红外热成像技术和激光驱鸟技术&#xff0c;极大地提升了夜间驱鸟工作的效率和安全性。 驱鸟技术详解&#xff1a; 在夜晚低能见度的环境下&#xff0c;红外热成…

基于开源项目ESP32 SVPWM驱动无刷电机开环速度测试

基于开源项目ESP32 SVPWM驱动无刷电机开环速度测试 ✨本篇硬件电路和代码来源于此开源项目&#xff1a;https://github.com/MengYang-x/STM3F401-FOC/tree/main&#x1f4cd;硬件电路和项目介绍&#xff0c;立创开源广场&#xff1a;https://oshwhub.com/shadow27/tai-yang-nen…

2024 HN CTF WebMisc 部分 wp

Web ez_tp 判断是thinkphp 3.2 参考官方手册:https://www.kancloud.cn/manual/thinkphp/1697 判断路由模式 URL_CASE_INSENSITIVE > true, // 默认false 表示URL区分大小写 true则表示不区分大小写URL_MODEL > 1, // URL访问模式,可选参数0、1、…

Python使用动态代理的多元应用

Python作为一种功能强大且易于学习的编程语言&#xff0c;在网络编程领域具有广泛的应用。当Python与动态代理技术结合时&#xff0c;便开启了一扇通往更多可能性的大门。以下将深入探讨Python使用动态代理可以实现的多种应用。 首先&#xff0c;Python结合动态代理在网络爬虫…

中文多模态InternVL-Chat-V1-5,中文理解能力强劲,8 项指标超越商业模型,性能媲美 GPT-4V

前言 近年来&#xff0c;多模态大型语言模型&#xff08;MLLM&#xff09;的快速发展&#xff0c;为人工智能在图像、文本等多模态信息理解和处理方面带来了前所未有的突破。然而&#xff0c;现有的主流多模态模型多以英文为训练语言&#xff0c;在中文理解和处理方面存在着明…

可用于嵌入式的解释器调研对比,及lua解释器介绍

嵌入式不一定只能用C! ---------------------------------------------------------------------------------------手动分割线-------------------------------------------------------------------------------- 本文章参考了以下文章&#xff1a; 这里是引用 ------------…

1113 钱串子的加法

idea 测试点3&#xff1a;输入的两个整数都是0测试点4.5&#xff1a;大数&#xff0c;需要用大数加法 solution1(测试点4&#xff0c;5不通过) 直接相加再转30进制 #include<iostream> #include<string> using namespace std; typedef long long ll; string a,…

linux sed命令替换文件端口

1、需求描述&#xff1a;因sed -i ‘s/旧端口/新端口/g’ 文件&#xff0c;替换会直接增加端口导致端口直接追加后面&#xff0c;因此需要修改 要求&#xff1a;2300替换为23003&#xff0c;23001替换为23004 <value>192.168.1.133</value></constructor-arg>…

windows 10下conda环境目录转移

目录 一&#xff1a;背景 二&#xff1a;转移过程 三&#xff1a;环境验证 一&#xff1a;背景 最近用conda安装了几个python环境&#xff0c;随着安装包和数据的不断增大&#xff0c;发现C盘占用空间一直在增加&#xff0c;已经有十几个G了&#xff0c;系统也变的越来越慢。…

【深度学习】安全帽检测,目标检测,yolov10算法,yolov10训练

文章目录 一、数据集二、yolov10介绍三、数据voc转换为yolo四、训练五、验证六、数据、模型、训练后的所有文件 寻求帮助请看这里&#xff1a; https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tabBB08J2一、数据集 安全帽佩戴检测 数据集&#xff1a;https://github.com/njvi…

MySql part1 安装和介绍

MySql part1 安装和介绍 数据 介绍 什么是数据库&#xff0c;数据很好理解&#xff0c;一般来说数据通常是我们所认识的 描述事物的符号记录&#xff0c; 可以是数字、 文字、图形、图像、声音、语言等&#xff0c;数据有多种形式&#xff0c;它们都以经过数字化后存入计算机…

Nuxt3项目实现 OG:Image

目录 前言 1、安装 2、设置网站 URL 3、启用 Nuxt DevTools 4、创建您的第一个Og:Image a. 定义OG镜像 b. 查看您的Og:Image 5、自定义NuxtSeo模板 a. 定义 NuxtSeo模板 b. 使用其他可用的社区模板 6、创建自己的模板 a. 定义组件 BlogPost.vue b. 使用新模板 c.…

python实训——回归类型数据挖掘任务

回归类型数据挖掘任务 基于ARIMA和多层神经网络模型的地铁站点日客流量预测。有郑州市2015年8月-11月各地铁闸机刷卡数据集。对每日各地铁站的客流量进行分析并进行可视化。基于上一步的分析结果&#xff0c;分别采用ARIMA模型和多层神经网络模型对数据进行建模&#xff0c;训…

Usage - hackthebox

简介 靶场&#xff1a;hackmyvm 靶机&#xff1a;Usage(10.10.11.18) 难度&#xff1a;Easy 靶机链接:https://app.hackthebox.com/machines/Usage 攻击机1&#xff1a;ubuntu22.04 (10.10.16.21) 攻击机2&#xff1a;windows11(10.10.14.33) 扫描 nmap起手 nmap -sT …

Centos7.9环境下keepalived结合nginx实现负载均衡的高可用(亲测版)

目录 一、负载均衡高可用解释 二、安装 三、Nginx检查脚本创建 四、修改keepalived配置文件 一、负载均衡高可用解释 nginx 作为负载均衡器&#xff0c;所有请求都到了nginx&#xff0c;如果nginx服务器宕机后端web服务将无法提供服务&#xff0c;影响严重。这样nginx作为负…

类和对象(中)【类的6个默认成员函数】 【零散知识点】 (万字)

类和对象&#xff08;中&#xff09; 1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1…

【Python】如何使用 Python 自动发送每日电子邮件报告

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

整合Spring Boot 框架集成Knife4j

本次示例使用Spring Boot作为脚手架来快速集成Knife4j,Spring Boot版本2.3.5.RELEASE ,Knife4j版本2.0.7 POM.XML完整文件代码如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0…

智能合约引领:探索Web3的商业革新之路

随着区块链技术的迅速发展&#xff0c;智能合约作为其重要应用之一&#xff0c;正在逐步改变着商业世界的格局。Web3作为下一代互联网的代表&#xff0c;正引领着智能合约在商业领域的广泛应用和创新。本文将深入探讨智能合约在Web3中的作用&#xff0c;以及智能合约如何引领着…