vue3+antd——实现个人中心页面+同步更改头部用户信息——基础积累

news2024/10/6 1:53:49

之前写过一篇文章关于vue3+antd的框架模板,链接如下:http://t.csdn.cn/9dZMS

首先感谢大神提供的后台管理系统的模板,在此基础上改动要简单很多,主要是自己有很多内容不太敢随意改动。。。

直接看【个人中心】页面的效果图:
在这里插入图片描述
个人中心的内容要跟框架头部的信息保持同步,因此需要用到vuex,此框架中的vuex是使用的pinia

下面介绍详细代码:

1.个人中心的页面代码

1.1html代码

<template>
  <a-spin :spinning="loading">
    <a-card>
      <a-tabs v-model="activeKey">
        <a-tab-pane key="1" tab="修改信息">
          <a-form
            :model="form"
            :rules="rules"
            style="height: calc(100vh - 200px); width: 60%; overflow: auto"
            ref="ruleForm"
            :label-col="labelCol"
            :wrapper-col="wrapperCol"
            @finish="handleOk"
          >
            <a-form-item label="用户名" ref="userName" name="userName">
              <a-input v-model:value="form.userName" placeholder="请输入角色名称" />
            </a-form-item>
            <a-form-item label="工号">
              <a-input v-model:value="form.jobNo" />
            </a-form-item>
            <a-form-item label="名">
              <a-input v-model:value="form.name" />
            </a-form-item>
            <a-form-item label="姓">
              <a-input v-model:value="form.surname" />
            </a-form-item>
            <a-form-item label="性别">
              <a-radio-group v-model:value="form.sex">
                <a-radio :value="1"></a-radio>
                <a-radio :value="2"></a-radio>
              </a-radio-group>
            </a-form-item>
            <a-form-item label="头像">
              <uploadPic
                v-model:value="form.headPhoto"
                listType="picture-card"
                :limit="1"
                :showFile="showFile"
                ref="upload"
                @getFile="headPhotoInput"
              ></uploadPic>
            </a-form-item>
            <a-form-item label="邮箱地址" ref="email" name="email">
              <a-input v-model:value="form.email" />
            </a-form-item>
            <a-form-item label="手机号码">
              <a-input v-model:value="form.phoneNumber" />
            </a-form-item>
            <a-button type="primary" style="margin-left: 20%" html-type="submit">保存</a-button>
          </a-form>
        </a-tab-pane>
        <a-tab-pane key="2" tab="修改密码">
          <a-form
            :model="form2"
            :rules="rules2"
            style="height: calc(100vh - 200px); width: 60%; overflow: auto"
            ref="ruleForm2"
            :label-col="labelCol"
            :wrapper-col="wrapperCol"
            @finish="handleOk2"
          >
            <a-form-item label="当前密码" name="currentPassword">
              <a-input v-model:value="form2.currentPassword" type="password" />
            </a-form-item>
            <a-form-item label="新密码" name="newPassword">
              <a-input v-model:value="form2.newPassword" type="password" />
            </a-form-item>
            <a-form-item label="确认新密码" name="newPasswordConfirm">
              <a-input v-model:value="form2.newPasswordConfirm" type="password" />
            </a-form-item>
            <a-button type="primary" style="margin-left: 20%" html-type="submit">保存</a-button>
          </a-form>
        </a-tab-pane>
      </a-tabs>
    </a-card>
  </a-spin>
</template>

1.2 js代码

<script lang="ts">
  import { GetUserInfo } from '@/services/storehouse/common';
  import { useAccountStore } from '@/store';
  import { createUpdate, postChangePassword } from '@/services/identity/user';
  import uploadPic from '@/components/upload/UploadPic.vue';
  export default {
    components: { uploadPic },
    data() {
      let validatePass = (rule, value) => {
        if (value === '') {
          return Promise.reject('请输入密码');
        } else if (value.length < 6) {
          return Promise.reject('密码长度不能少于6位');
        } else {
          return Promise.resolve();
        }
      };
      let validatePass1 = (rule, value) => {
        if (value === '') {
          return Promise.reject('请输入密码');
        } else if (value.length < 6) {
          return Promise.reject('密码长度不能少于6位');
        } else {
          return Promise.resolve();
        }
      };
      let validatePass2 = (rule, value) => {
        if (value === '') {
          return Promise.reject('请输入密码');
        } else if (value.length < 6) {
          return Promise.reject('密码长度不能少于6位');
        } else {
          return Promise.resolve();
        }
      };
      return {
        showFile: [],
        loading: false,
        activeKey: '1',
        labelCol: { span: 6 },
        wrapperCol: { span: 18 },
        form: {
          userName: null,
          jobNo: null,
          name: null,
          surname: null,
          sex: null,
          headPhoto: null,
          email: null,
          phoneNumber: null,
        },
        form2: {
          currentPassword: null,
          newPassword: null,
          newPasswordConfirm: null,
        },
        rules2: {
          currentPassword: [
            { required: true, message: '请输入密码', trigger: 'blur' },
            { validator: validatePass, trigger: 'change' },
          ],
          newPassword: [
            { required: true, message: '请输入密码', trigger: 'blur' },
            { validator: validatePass1, trigger: 'change' },
          ],
          newPasswordConfirm: [
            { required: true, message: '请输入密码', trigger: 'blur' },
            { validator: validatePass2, trigger: 'change' },
          ],
        },
        rules: {
          userName: [{ required: true, message: '用户名必须填写', trigger: 'blur' }],
          email: [
            {
              type: 'email',
              required: true,
              message: '请填写正确的邮箱地址',
              trigger: 'blur',
            },
          ],
        },
      };
    },
    methods: {
      headPhotoInput(imgs) {
        this.form.headPhoto = imgs;
        this.$forceUpdate();
      },
      getUserInfo(flag) {
        this.loading = true;
        GetUserInfo()
          .then((res: any) => {
            if (res.code == 1) {
              this.form = {
                ...res.data,
                headPhoto: res.data?.extraProperties?.HeadPhoto,
                jobNo: res.data?.extraProperties?.JobNo,
              };
              if (flag) {
                const { setUser } = useAccountStore();
                setUser({ ...this.form });
              }
              this.form2 = {
                id: res.data.id,
              };
              if (this.form.headPhoto) {
                this.showFile = [
                  {
                    name: this.form.headPhoto,
                    url: this.form.headPhoto,
                    uid: this.form.headPhoto,
                  },
                ];
              } else {
                this.showFile = [];
              }
            }
          })
          .finally(() => {
            this.loading = false;
          });
      },
      handleOk2() {
        this.loading = true;
        postChangePassword(this.form2)
          .then((res) => {
            this.$message.success('操作成功');
            this.getUserInfo();
          })
          .finally(() => {
            this.loading = false;
          });
      },
      handleOk() {
        this.loading = true;
        let values = {
          ...this.form,
          extraProperties: {
            JobNo: this.form.jobNo,
            HeadPhoto: this.form.headPhoto,
          },
        };
        createUpdate(values)
          .then((res) => {
            this.$message.success('操作成功');
            this.getUserInfo(true);
          })
          .finally(() => {
            this.loading = false;
          });
      },
    },
    activated() {
      this.getUserInfo();
    },
  };
</script>

重点在于:修改个人信息后,需要触发account.js中的setUser方法,然后将内容同步到头部。

也就是再handleOk的函数调用成功后,要重新获取用户信息getUserInfo的方法,在此方法中要进行account.ts中的setUser方法。

1.3 account.ts中的setUser方法——重要代码!!!

export const useAccountStore = defineStore('account', {
  state: () => ({
    account: null,
  }),
  actions: {   
  	setUser(userInfo) {
      this.account = userInfo;
    },
  },
});

获取account.ts中的方法如下:

import { useAccountStore } from '@/store';

getUserInfo中的方法如下:

if (flag) {
  const { setUser } = useAccountStore();
  setUser({ ...this.form });
}

此时就实现了个人信息修改后与后台管理系统头部信息的同步。

2.上传头像的组件——uploadPic

2.1 html代码:

<template>
  <div>
    <a-upload
      class="upload-demo"
      :customRequest="uploadFile"
      @remove="handleRemove"
      :file-list="fileList"
      :multiple="multiple"
      :limit="limit"
      :list-type="listType"
    >
      <a-button v-if="showBtn" size="small" type="primary">点击上传</a-button>
      <plus-outlined v-if="!showBtn && fileList.length < limit" />
      <template v-slot:tip>
        <div class="cloud-upload"></div>
      </template>
    </a-upload>
    <a-modal title="图片预览" :visible="dialogVisible" :append-to-body="true">
      <img width="100%" :src="dialogImageUrl" alt="" />
    </a-modal>
  </div>
</template>

2.2 js代码

<script lang="ts">
  import { Upload } from '@/services/storehouse/common.js';
  export default {
    name: 'UploadPic',
    props: {
      multiple: {
        type: Boolean,
        default: false,
      },
      showFile: Array,
      limit: Number,
      showBtn: {
        type: Boolean,
        default: false,
      },
      listType: String,
    },
    data() {
      return {
        fileList: [],
        dialogVisible: false,
        dialogImageUrl: '',
      };
    },
    watch: {
      showFile: {
        handler(newVal) {
          this.fileList = newVal ? newVal : [];
        },
        deep: true,
        immediate: true,
      },
    },
    methods: {
      uploadFile(req) {
        let that = this;
        let formData = new FormData();
        formData.append('files', req.file);
        Upload({ module: 'IQC' }, formData).then((response: any) => {
          if (response.code == 0) return false;
          that.fileList.push({
            uid: req.file.uid,
            name: req.file.name,
            url: response.data,
          });
          let imgs = that.fileList.map((s) => s.url).join(',');
          this.$emit('getFile', imgs);
        });
      },
      beforeUpload() {},
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
      handleRemove(file) {
        let index = this.fileList.findIndex((item) => {
          return item.uid === file.uid;
        });
        this.fileList.splice(index, 1);
        let imgs = this.fileList.map((s) => s.url).join(',');
        this.$emit('getFile', imgs);
      },
      beforeRemove(file, fileList) {
        return this.$confirm(`确定移除文件?`);
      },
      handleExceed(files, fileList) {
        this.$message.warning(
          `当前限制选择${this.limit}个文件,本次选择了 ${files.length} 个文件,共选择了 ${
            files.length + fileList.length
          } 个文件`
        );
      },
    },
  };
</script>

2.3 Upload接口——要根据实际情况来处理

//上传图片 
export async function Upload(params, data) {
  return request(`/api/app/bussiness-smt/upload-file?${qs.stringify(params)}`, METHOD.POST, data, {
    headers: {
      AppSecret: 'xxxxxxxxx',
    },
  });
}

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

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

相关文章

JavaScript事件委托与事件流+牛客例题

事件流&#xff1a; 概念&#xff1a;事件完整执行过程中的流动路径 说明&#xff1a;假设页面里有个div&#xff0c;当触发事件时&#xff0c;会经历两个阶段&#xff0c;分别是捕获阶段、冒泡阶段 简单来说&#xff1a;捕获阶段是 从父到子 冒泡阶段是从子到父 注意&…

TEMU美国儿童文具亚马逊CPC测试标准

美国站儿童文具类上架跨境电商平台美国站或者出口美国需要提交CPC认证&#xff0c;才能进入美国市场&#xff0c;由CPSC 认可的实验室出具的检测报告&#xff0c;确认每件商品均已过检测&#xff0c;符合上述适用要求。但许多亚马逊卖家反映&#xff1a;在亚马逊卖的文具类产品…

哪个思维导图软件好,知道这5个就够了!

思维导图作为一种有效的组织和展示思维的工具&#xff0c;广泛应用于学习、项目管理、创意发展等领域。然而&#xff0c;手工绘制思维导图费时费力&#xff0c;限制了其在快节奏的现代生活中的应用。本文将介绍5款可以一键生成思维导图的软件&#xff0c;它将通过智能化的方式&…

Chrome 谷歌浏览器,自动填充密码,提示需要输入电脑开机密码问题

我们在使用浏览器访问各个网站时&#xff0c;经常会保存密码。在下一次访问时&#xff0c;直接使用保存的密码填充&#xff0c;简单方便。 但是突然有一天&#xff08;怀疑是谷歌浏览器更新导致的&#xff09;&#xff0c;每次使用密码填充时&#xff0c;都有如下拦截 拦截提…

前端 select 标签如何创建下拉菜单?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 代码示例⭐ 代码讲解⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏…

PyTorch中ReduceLROnPlateau的学习率调整优化器

PyTorch中ReduceLROnPlateau的学习率调整优化器 作者&#xff1a;安静到无声 个人主页 简介&#xff1a; 在深度学习中&#xff0c;学习率是一个重要的超参数&#xff0c;影响模型的收敛速度和性能。为了自动调整学习率&#xff0c;PyTorch提供了ReduceLROnPlateau优化器&…

Linux IPIP隧道连通两个局域网

拓扑结构 现有两台主机&#xff0c;它们具有两个网口分别接入到不同网络中。 主机A&#xff1a; eth0&#xff1a;处于 10.0.1.2/24 网段eth1&#xff1a; 处于192.168.1.100/24 网段 主机B&#xff1a; eth0&#xff1a;处于10.0.2.3/24 网段eth1&#xff1a; 处于192.168.2…

持续同步的实时备份软件推荐!

什么是实时备份&#xff1f; 实时备份是一种持续数据保护方法&#xff0c;通过缩短自动保存文件的时间间隔&#xff0c;可以备份每个更改的副本&#xff0c;以捕获保存数据的每个版本。 传统备份方式只能将数据还原到备份完成时的状态&#xff0c;如果在故障发生时进行恢复…

收藏!!!一起来学习IGBT基础知识。

1 IGBT是什么&#xff1f; IGBT&#xff0c;绝缘栅双极型晶体管&#xff0c;是由&#xff08;BJT&#xff09;双极型三极管和绝缘栅型场效应管&#xff08;MOS&#xff09;组成的复合全控型电压驱动式功率半导体器件, 兼有&#xff08;MOSFET&#xff09;金氧半场效晶体管的高…

init_pg_dir 的大小及作用

init_pg_dir 的大小 vmlinux.lds.S 中 在vmlinux.lds.S 中&#xff0c;有 init_pg_dir .; . INIT_DIR_SIZE; init_pg_end .;/*include/asm/kernel-pgtable.h*/ #define EARLY_ENTRIES(vstart, vend, shift) \ ((((vend) - 1) >&g…

Zebec Protocol 将进军尼泊尔市场,通过 Zebec Card 推动该地区金融平等

流支付正在成为一种全新的支付形态&#xff0c;Zebec Protocol作为流支付的主要推崇者&#xff0c;正在积极的推动该支付方案向更广泛的应用场景拓展。目前&#xff0c;Zebec Protocol成功的将流支付应用在薪酬支付领域&#xff0c;并通过收购WageLink将其纳入旗下&#xff0c;…

3.7v升压5v4A芯片用什么型号

问&#xff1a;我需要一个能够将3.7V锂电池的电压升压到5V&#xff0c;并且能够提供4A的电流输出的芯片。请问有什么推荐的型号吗&#xff1f; 答&#xff1a;小编为您推荐AH6922B芯片&#xff0c;它具备以下特点来满足您的需求&#xff1a; 1. 输入电压范围适配&#xff1a;…

SAP 计划独立需求屏幕增强(MD61/MD62/MD63)

需求&#xff1a;在计划独立需求界面新增一列自定义字段 效果如下&#xff1a; MD63&#xff1a;显示:&#xff08;注&#xff1a;客户字段在显示界面不可以编辑&#xff09; MD61&#xff1a;创建/MD62&#xff1a;修改&#xff08;注&#xff1a;创建和修改的时候客户字段可…

C语言学习笔记 vscode使用外部console-11

前言 在默认情况下&#xff0c;我们运行C语言程序都是在vscode终端的&#xff0c;在小程序运行时这个是没有问题的&#xff0c;但是当程序变得复杂它就不好用了&#xff0c;这时我们可以将这个终端设置为外部console&#xff0c;这样方便处理更多、更复杂的程序。 步骤 1.点击…

4基础篇:自定义日志

前言 在所有的后端服务中,日志是必不可少的一个关键环节,毕竟日常中我们不可能随时盯着控制台,问题的出现也会有随机性、不可预见性。一旦出现问题,要追踪错误以及解决,需要知道错误发生的原因、时间等细节信息。 之前的需求分析部分,在网关基础代理的服务中,网关作为…

局域网内共享打印机遇到的一些问题

局域网内共享打印机遇到的一些问题 常规共享步骤主机关机后开机&#xff0c;打印机用不起了报错&#xff1a;没有权限使用报错&#xff1a;Windows无法连接到打印机报错&#xff1a;0x0000011b报错&#xff1a;0x00000709 常规共享步骤 win7作为主机使用USB连接打印机&#xf…

Python AI 绘画

Python AI 绘画 本文我们将为大家介绍如何基于一些开源的库来搭建一套自己的 AI 作图工具。 需要使用的开源库为 Stable Diffusion web UI&#xff0c;它是基于 Gradio 库的 Stable Diffusion 浏览器界面 Stable Diffusion web UI GitHub 地址&#xff1a;GitHub - AUTOMATI…

【Git】Git切换地址

如何切换git代码地址&#xff1f; 1、查看当前远程 url git remote -v执行命令后&#xff0c;可以看见当前有2个URL。 远程 URL 在一般情况下有两个&#xff0c;分别是 fetch 和 push。 fetch URL 是用于从远程仓库获取最新版本的数据。当您运行 git fetch 命令时&#xf…

【福建事业单位-数学运算】01 数学推理-基础-特征-非特征数列

【福建事业单位-数学运算】01 数学推理-基础-特征-非特征数列 一、基础数列总结 二、特征数列2.1 多重数列项数多&#xff0c;多于7项总结 2.2机械划分①小数;ab②大数字多&#xff08;三位数、四位数&#xff09;&#xff0c;达到一半或者以上总结 2.3分数数列大通分总结 2.4幂…

成品短视频App源码开发:一步步教你搭建短视频平台

近年来&#xff0c;短视频平台的兴起迅速改变了人们对视频内容的获取方式&#xff0c;成品短视频App源码的开发也因此备受瞩目。对于希望快速搭建短视频平台的创业者来说&#xff0c;使用成品短视频App源码是一个明智的选择。 成品短视频App源码为您提供了一个基于现有技术和功…