vue3项目之大事件管理系统(四) 二级路由:个人中心页的实现,用AI大模型开发整个项目模块

个人中心

在这里插入图片描述
个人中心分为三个部分,基本资料UserProfile.vue,更换头像UserAvatar.vue和重置密码UserPassword.vue,它们是三个嵌套在首页下的二级路由页

1.基本资料

在这里插入图片描述
基本资料页(user/UserProfile.vue)有如下需求:

  • 静态布局
  • 对用户昵称和用户邮箱配置校验规则
  • 实现提交修改功能
静态结构和校验
  • deekseek搜索词prompt如下:
请基于 elementPlus 和 Vue3 的语法,生成组件代码
要求:
一、表单结构要求
1.  组件中包含一个el-form表单,有四行内容,前三行是输入框,第四行是按钮
2. 第一行 label 登录名称,输入框禁用不可输入状态
3. 第二行 label 用户昵称,输入框可输入
4. 第三行 label 用户邮箱,输入框可输入
5. 第四行按钮,提交修改

二、校验需求
给昵称 和 邮箱添加校验
1. 昵称 nickname 必须是2-10位的非空字符串
2. 邮箱 email 符合邮箱格式即可,且不能为空
  • 完整代码和注释
//UserProfile.vu
<script setup>
import { useUserStore } from '@/stores'
import { ref } from 'vue'
//读取存在本地的user
// {id: 51452, username: "bear3", nickname: "", email: "", user_pic: null}
const {
  user: { username, nickname, email, id }
} = useUserStore()
//step1:准备表单数据对象,用于双向绑定表单项的值
const userInfo = ref({ username, nickname, email, id })
// step2:准备校验规则的rules对象
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>
  <page-container title="基本资料">
    <el-row>
      <el-col :span="12">
        <!-- :model和:rules分别动态绑定userinfo和rules -->
        <el-form :model="userInfo" :rules="rules" ref="formRef" label-width="100px" size="large">
          <!-- 登录名称不用校验 -->
          <el-form-item label="登录名称">
            <el-input v-model="userInfo.username" disabled></el-input>
          </el-form-item>
          <!-- 用户昵称的校验:step3-配置props以示生效的是nickname规则 -->
          <el-form-item label="用户昵称" prop="nickname">
            <!-- step4:v-model动态绑定指定校验规则为rules中的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>
  </page-container>
</template>

封装接口

在这里插入图片描述
在这里插入图片描述

//api/user.js

/*个人中心-基本资料*/
// 更新个人信息
export const userUpdateInfoService = ({ id, username, nickname }) => {
  return request.put('/my/userinfo', { id, username, nickname })
}
页面调用
import { useUserStore, getUser } from '@/stores'
import { userUpdateInfoService } from '@/api/user'
const formRef = ref()
const onSubmit = async () => {
  // 提交前预校验表单,返回布尔值
  const valid = await formRef.value.validate()
  if (valid) {//校验通过,发起修改用户信息的请求
    await userUpdateInfoService(userInfo.value)//发起修改用户信息的请求
    await getUser()//刷新用户信息
    ElMessage.success('修改成功')
  }
}

<el-button type="primary" @click="onSubmit">提交修改</el-button>
2.更换头像

在这里插入图片描述

更换头像页(user/UserAvatar.vue)有如下需求:

  • 静态布局
  • 选择更换的头像
  • 实现新头像的上传
静态结构
<script setup>
import { ref } from 'vue'
import { Plus, Upload } from '@element-plus/icons-vue'
import { useUserStore } from '@/stores'

const userStore = useUserStore()

const imgUrl = ref(userStore.user.user_pic)
const onUploadFile = (file) => {
  console.log(file)
}
</script>

<template>
  <page-container title="更换头像">
    <el-row>
      <el-col :span="12">
        <el-upload ref="uploadRef" class="avatar-uploader" :auto-upload="false" :show-file-list="false"
          :on-change="onUploadFile">
          <img v-if="imgUrl" :src="imgUrl" class="avatar" />
          <!-- <img v-else src="@/assets/avatar.jpg" width="278" /> -->
          <img v-else width="278"
            src="https://img2.baidu.com/it/u=2527990145,2068681281&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=PNG?w=500&amp;h=500">
        </el-upload>
        <br />
        <el-button type="primary" :icon="Plus" size="large">
          选择图片
        </el-button>
        <el-button type="success" :icon="Upload" size="large">
          上传头像
        </el-button>
      </el-col>
    </el-row>
  </page-container>
</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>

选择预览图片
const uploadRef = ref()// 拿到上传组件的实例
const imgUrl = ref(userStore.user.user_pic)// 头像地址
const onUploadFile = (file) => {// 文件上传前的回调函数
  // 创建一个FileReader对象
  const reader = new FileReader()
  // 将文件读取为DataURL
  reader.readAsDataURL(file.raw)
  // 当文件读取完成后触发的事件处理函数
  reader.onload = () => {
    // 将读取到的文件内容赋值给imgUrl的value属性
    imgUrl.value = reader.result
  }
}
<!-- 点击选择图片时,会触发input的click事件, 这里通过js手动触发点击事件 -->
<el-button @click="uploadRef.$el.querySelector('input').click()" type="primary" :icon="Plus"
  size="large">选择图片</el-button>
上传头像
  • 封装接口
    在这里插入图片描述
    在这里插入图片描述
/*个人中心-更换头像*/
// 上传头像
export const userUploadAvatarService = ({ avatar }) => {
  return request.patch('/my/update/avatar', { avatar })
}
  • 页面调用
import { userUploadAvatarService } from '@/api/user'
import { useUserStore } from '@/stores'

// 点击事件: 更换头像
const onUpdateAvatar = async () => {
  await userUploadAvatarService(imgUrl.value)// 调用上传头像的接口
  await userStore.getUser()// 重新获取用户信息, 更新头像
  ElMessage({ type: 'success', message: '更换头像成功' })
}
<el-button type="success" :icon="Upload" size="large" @click="onUpdateAvatar">
  上传头像
</el-button>
3.重置密码

在这里插入图片描述
重置密码页(user/UserPassword.vue)有如下需求:

  • 静态布局
  • 三个文本框的校验
  • 修改密码功能的实现
  • 重置表单的实现
静态结构和校验
  • deepseek搜索词prompt:
请基于 elementPlus 和 Vue3 的语法,生成组件代码
要求:
一、表单结构要求
1. 组件中包含一个el-form表单,有四行内容,前三行是表单输入框,第四行是两个按钮
2. 第一行 label 原密码
3. 第二行 label 新密码
4. 第三行 label 确认密码
5. 第四行两个按钮,修改密码 和 重置

二、form绑定字段如下:
const pwdForm = ref({
  old_pwd: '',
  new_pwd: '',
  re_pwd: ''
})

三、校验需求
所有字段,都是 6-15位 非空
自定义校验1:原密码 和 新密码不能一样
自定义校验2:新密码 和 确认密码必须一样

  • 获得的静态页面如下:
<script setup>
import { ref } from 'vue'
const pwdForm = ref({// 定义一个响应式对象pwdForm,用于存储表单数据
  old_pwd: '',
  new_pwd: '',
  re_pwd: ''
})
const checkOldSame = (rule, value, cb) => {
  // 判断新密码是否与旧密码相同
  if (value === pwdForm.value.old_pwd) {
    // 如果新密码与旧密码相同,则调用回调函数并传入错误信息
    cb(new Error('原密码和新密码不能一样!'))
  } else {
    // 如果新密码与旧密码不同,则直接调用回调函数
    cb()
  }
}

const checkNewSame = (rule, value, cb) => {
  // 判断输入的值是否与pwdForm中的new_pwd字段值不同
  if (value !== pwdForm.value.new_pwd) {
    // 如果不同,则回调cb并传入错误信息
    cb(new Error('新密码和确认再次输入的新密码不一样!'))
  } else {
    // 如果相同,则直接调用cb,不传入任何参数
    cb()
  }
}

/*校验规则的四个步骤:略 */
const rules = {
  old_pwd: [// 原密码校验:非空+长度校验
    { required: true, message: '请输入密码', trigger: 'blur' },
    {
      pattern: /^\S{6,15}$/,
      message: '密码长度必须是6-15位的非空字符串',
      trigger: 'blur'
    }
  ],
  new_pwd: [// 新密码校验:非空+长度校验+与旧密码不同(自定义校验规则)
    { required: true, message: '请输入新密码', trigger: 'blur' },
    {
      pattern: /^\S{6,15}$/,
      message: '密码长度必须是6-15位的非空字符串',
      trigger: 'blur'
    },
    { validator: checkOldSame, trigger: 'blur' }
  ],
  re_pwd: [// 确认新密码校验:非空+长度校验+与新密码相同(自定义校验规则)
    { required: true, message: '请再次确认新密码', trigger: 'blur' },
    {
      pattern: /^\S{6,15}$/,
      message: '密码长度必须是6-15位的非空字符串',
      trigger: 'blur'
    },
    { validator: checkNewSame, trigger: 'blur' }
  ]
}
</script>
<template>
  <page-container title="重置密码">
    <el-row>
      <el-col :span="12">
        <el-form :model="pwdForm" :rules="rules" ref="formRef" label-width="100px" size="large">
          <el-form-item label="原密码" prop="old_pwd">
            <el-input v-model="pwdForm.old_pwd" type="password"></el-input>
          </el-form-item>
          <el-form-item label="新密码" prop="new_pwd">
            <el-input v-model="pwdForm.new_pwd" type="password"></el-input>
          </el-form-item>
          <el-form-item label="确认新密码" prop="re_pwd">
            <el-input v-model="pwdForm.re_pwd" type="password"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button @click="onSubmit" type="primary">修改密码</el-button>
            <el-button @click="onReset">重置</el-button>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
  </page-container>
</template>

封装接口

在这里插入图片描述
在这里插入图片描述

/*个人中心-修改密码*/
// 修改密码
export const userUpdatePassService = ({ old_pwd, new_pwd, re_pwd }) => {
  return request.patch('/my/updatepwd', { old_pwd, new_pwd, re_pwd })
}
页面调用
    await userUpdatePassService(pwdForm.value)
    // 显示成功消息
    ElMessage({ type: 'success', message: '更换密码成功' })
    // 清空token
    userStore.setToken('')
    // 清空用户信息
    userStore.setUser({})
    // 重定向到登录页面
    router.push('/login')
  }
}
//点击重置表单
const onReset = () => {
  formRef.value.resetFields()// 重置表单字段
}
<el-button @click="onSubmit" type="primary">修改密码</el-button>
<el-button @click="onReset">重置</el-button>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端OnTheRun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值