【Vue3大事件 | 项目笔记】第二天

前言:Vue3大事件项目是一个基于Vue3的PC端项目,本系列文章我将总结我在这个项目中学到的知识点,写项目笔记。如果你正好在学或巩固Vue3,希望本系列文章可以帮助到你。

【Vue3大事件 | 项目笔记】第二天

今日完结:

  • 用Pinia构建用户仓库并持久化
  • 请求工具设计
  • 路由的设计和配置
  • 登录注册页结构渲染

今日收获:

1.用Pinia持久化

当用户输入信息时,若希望输入的内容在页面刷新后不丢失,且该信息需要在多个组件 / 页面中共享,我们可以用 Pinia 管理这些输入状态,并通过 Pinia 持久化插件(如 pinia-plugin-persistedstate)将状态同步到浏览器本地存储(localStorage/sessionStorage),从而实现数据的持久化保存。

步骤:

1.安装插件

javascript 复制代码
pnpm add pinia-plugin-persistedstate -D

2.使用 main.js

javascript 复制代码
import persist from 'pinia-plugin-persistedstate'
...
app.use(createPinia().use(persist))

3.配置 stores/user.js

javascript 复制代码
import { defineStore } from 'pinia'
import { ref } from 'vue'

// 用户模块
export const useUserStore = defineStore(
  'big-user',
 ...
  {
    persist: true // 持久化
  }
)

2.掌握仓库统一导出

引入一个仓库书写方式: import { useUserStore } from ./stores/modules/user.js ,写起来很长,同时不同仓库路径不一致,导致很麻烦。为解决不同 Pinia 仓库导入路径不统一、书写麻烦的问题,我们可以把所有仓库文件集中放在 stores/modules 目录管理,同时在 stores/index.js 中统一导出这些仓库,这样业务组件只需从 ./stores 这一个路径导入,无需记忆各仓库的具体路径。

在stores中的index.js文件里面配置

javascript 复制代码
export * from './modules/user'
//等同于 import {useUserStore} from './modules/user'
//      export {userCountStore}

3.学会请求工具的设计

像我们平时写的分散代码,具有每个接口请求都需重复编写 baseURL、超时时间、token 携带、错误处理等逻辑,项目接口越多,重复代码量越大;若需修改鉴权规则(如 token 字段名变更)、调整超时时间,或更换提示组件(如从 ElMessage 换为其他组件),需逐个修改所有接口请求代码等问题。这时我们可以进行请求工具的统一设计。

请求工具的设计核心优势:复用通用请求逻辑、统一全局请求规则、降低维护成本、提升扩展性和用户体验。

新建 utils/request.js 封装 axios 模块

javascript 复制代码
import axios from 'axios'
import { useUserStore } from '@/stores'
import { ElMessage } from 'element-plus'
import router from '@/router'
const baseURL = 'http://big-event-vue-api-t.itheima.net'

const instance = axios.create({
  // TODO 1. 基础地址,超时时间
  baseURL,
  timeout: 10000
})

instance.interceptors.request.use(
  (config) => {
    // TODO 2. 携带token
    const userStore = useUserStore()
    if (userStore.token) {
      config.headers.Authorization = userStore.token
    }

    return config
  },
  (err) => Promise.reject(err)
)

instance.interceptors.response.use(
  (res) => {
    // TODO 4. 摘取核心响应数据
    if (res.data.code === 0) {
      return res
    }
    // TODO 3. 处理业务失败
    ElMessage.error(res.data.message || '服务异常')

    return Promise.reject(res.data)
  },
  (err) => {
    // TODO 5. 处理401错误
    if (err.response?.status === 401) {
      router.push('/login')
    }
    ElMessage.error(err.response.data.message || '服务异常')
    return Promise.reject(err)
  }
)

export default instance
export { baseURL }

4.用Element进行注册登录静态结构渲染

和纯手写 HTML 搭建页面结构的方式相比,这里的静态结构渲染依托 Element Plus组件库实现:组件库已预制好 el-row(行)、el-col(列)、el-form(表单)等通用 UI 组件的结构和样式,直接调用即可,无需从零编写布局和表单的基础代码,大幅提升页面开发效率。

javascript 复制代码
<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
const isRegister = ref(true)
</script>

<template>
  <el-row class="login-page">
    <el-col :span="12" class="bg"></el-col>
    <el-col :span="6" :offset="3" class="form">
      <el-form ref="form" size="large" autocomplete="off" v-if="isRegister">
        <el-form-item>
          <h1>注册</h1>
        </el-form-item>
        ....
        </el-form>
       
      ...
       <el-form ref="form" size="large" autocomplete="off" v-else>
        <el-form-item>
          <h1>登录</h1>
        </el-form-item> 
     ...
      </el-form>
    </el-col>
  </el-row>
</template>

5.表单校验

同时element也提供了用户进行登录和注册时的表单校验。

(1) el-form => :model="ruleForm"

绑定的整个 form 的数据对象 { xxxx, xxxx, xxxx }

javascript 复制代码
const formModel = ref({
  username: '',
 ...
})
<el-form :model="formModel" >

(2) el-form => :rules="rules"

绑定的整个 rules 规则对象 { xxxx, xxxx, xxxx }

javascript 复制代码
<el-input
  v-model="formModel.username"
  :prefix-icon="User"
  placeholder="请输入用户名"
></el-input>

(3) 表单元素 => v-model="ruleForm.xxx"

给表单元素,绑定 form 的子属性

javascript 复制代码
<el-form :rules="rules" >
    
const rules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 5, max: 10, message: '用户名必须是5-10位的字符', trigger: 'blur' }
  ],
}

(4) prop 配置生效的是哪个校验规则

javascript 复制代码
<el-form-item prop="username">
  <el-input
    v-model="formModel.username"
    :prefix-icon="User"
    placeholder="请输入用户名"
  ></el-input>
</el-form-item>

这样就实现了用户在进行用户名填写的时候,必须遵循"用户名必须是5-10位的字符,不能为空"的规则。

注册前的预校验

注册前的预校验,是指用户在提交注册表单(如点击 "注册" 按钮)前,前端对输入的信息(用户名、手机号、邮箱、密码等)进行即时的规则验证,而非直接提交到后端。

好处:减少无效的后端请求,降低服务器压力,提升用户体验,即时反馈错误。

步骤:

1.通过 ref 获取到 表单组件

javascript 复制代码
const form = ref()

<el-form ref="form">

2.通过 ref 获取到 表单组件

javascript 复制代码
<el-button
  @click="register"
  class="button"
  type="primary"
  auto-insert-space
>
  注册
</el-button>

const register = async () => {
  await form.value.validate()  //预校验
  console.log('开始注册请求')
}

杂项知识点:

注册和登录切换问题

在注册 / 登录表单通过 v-if 切换时,用户已填写的 "用户名""密码" 等表单内容会残留(切换后仍显示在另一表单中);为解决该问题,我们可以监听切换条件(如 isRegister)的变化,在切换触发时,调用表单重置方法清空已输入的内容,保证两个表单的数据互不干扰。

javascript 复制代码
watch(isRegister,()=>{
  formModel.value = {
  username: '',
  password: '',
  repassword: ''
  }
})

Pinia存储和localStorage直接存储区别

Pinia存储和localStorage直接存储本质最终都实现数据持久化,但两者两种完全不同的状态管理方式。

核心区别:Pinia是Vue专属的响应式内存状态管理库,支持任意JS类型,数据变更组件自动更新,适合跨组件共享的复杂状态(持久化需插件);localStorage是浏览器本地存储API,仅存字符串、无响应式,需手动序列化/反序列化,适合简单数据的持久化,无需跨组件共享时更轻便。

总结:

今天了解到了Element组件库里面的很多知识,也学会了很多优化代码的逻辑。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

相关推荐
额1292 小时前
Docker搭建zabbix
笔记
万码社2 小时前
小程序开发实战:我手写日历组件踩过的那些坑
前端
工藤新一¹2 小时前
《操作系统》第一章(1)
java·服务器·前端
用户9714171814272 小时前
Flex 和 Grid 详细使用指南:从入门到实战避坑
前端·css
不会敲代码12 小时前
使用 Mock.js 模拟 API 数据,实现前后端并行开发
前端·javascript
琛説2 小时前
Web-Rooter:一种 IR + Lint 模式的 AI Agent 创新尝试【或许是下一个 AI 爆火方向】
前端·人工智能
killer Curry2 小时前
Polar CTF PWN 简单(1)(持续更新)
笔记·python·算法
用户9714171814272 小时前
absolute 元素的包含块(containing block)怎么找
前端·css
青山Coding2 小时前
Cesium应用(四):全球台风气象可视化实现
前端·vue.js·cesium