当前位置: 首页 > news >正文

Vue3 进阶,新特性 defineOptions/defineModel+Pinia 状态管理全解析

Vue3.3 + 新增了defineOptionsdefineModel等实用语法糖,而Pinia则是 Vue3 官方推荐的状态管理工具(替代 Vuex)。

一、Vue3.3 新特性:语法糖简化开发

Vue3.3 推出了多个语法糖,核心是减少模板代码、提升开发效率。

1.defineOptions:简化组件选项

在 Vue3 中,组件的nameinheritAttrs等选项需要单独写在export default中,defineOptions可以直接在<script setup>中定义这些选项。
用法示例:

<script setup> // 直接在setup中定义组件选项 defineOptions({ name: 'MyComponent', // 组件名(用于keep-alive等场景) inheritAttrs: false // 禁止属性继承到根元素 }) </script>

替代的旧写法:

<script setup> // 旧写法:需要额外写export default </script> <script> export default { name: 'MyComponent', inheritAttrs: false } </script>

2.defineModel:简化双向绑定(v-model

在 Vue3 中,子组件实现v-model需要同时处理propsemitdefineModel可以一行代码实现双向绑定。
用法示例:
子组件(Input.vue):

<script setup> // 用defineModel定义双向绑定的属性 const modelValue = defineModel() </script> <template> <!-- 直接绑定到输入框 --> <input v-model="modelValue" /> </template>

父组件:

<script setup> import Input from './Input.vue' import { ref } from 'vue' const msg = ref('') </script> <template> <!-- 直接使用v-model --> <Input v-model="msg" /> <p>输入内容:{{ msg }}</p> </template>

替代的旧写法:

<!-- 子组件旧写法 --> <script setup> const props = defineProps(['modelValue']) const emit = defineEmits(['update:modelValue']) </script> <template> <input :value="props.modelValue" @input="emit('update:modelValue', $event.target.value)" /> </template>

二、Pinia:Vue3 官方状态管理工具

Pinia 是 Vue3 官方推荐的状态管理库,相比 Vuex 更轻量、更简洁,原生支持 TypeScript,是 Vue3 项目的首选。

1. 什么是 Pinia?

Pinia 可以理解为Vuex 的升级版,核心特点:

  • Mutations:直接在Action中修改状态;
  • 更简洁的 API:仅需defineStore定义仓库;
  • 原生支持 TS:类型提示更友好;
  • 轻量:打包体积仅 1KB 左右。

2. 手动添加 Pinia 到 Vue 项目

步骤 1:安装 Pinia

npminstallpinia

步骤 2:在入口文件注册 Pinia

// main.jsimport{createApp}from'vue'import{createPinia}from'pinia'// 引入PiniaimportAppfrom'./App.vue'constapp=createApp(App)app.use(createPinia())// 注册Piniaapp.mount('#app')

3. Pinia 的基本语法:defineStore

通过defineStore定义一个 “仓库(Store)”,每个仓库管理一块全局状态。
示例:定义用户仓库(userStore)

// src/stores/user.jsimport{defineStore}from'pinia'import{ref}from'vue'// 第一个参数:仓库唯一标识;第二个参数:仓库配置exportconstuseUserStore=defineStore('user',()=>{// 1. 状态(对应Vuex的state)constuserInfo=ref(null)consttoken=ref('')// 2. 计算属性(对应Vuex的getters)constisLogin=()=>{return!!token.value}// 3. 方法(对应Vuex的actions,支持异步)constlogin=async(form)=>{// 模拟接口请求constres=awaitnewPromise(resolve=>{setTimeout(()=>{resolve({userInfo:{name:'张三',age:20},token:'pinia_token_123'})},1000)})// 直接修改状态(无需Mutations)userInfo.value=res.userInfo token.value=res.token}constlogout=()=>{userInfo.value=nulltoken.value=''}// 返回需要暴露的状态、计算属性、方法return{userInfo,token,isLogin,login,logout}})

4. 在组件中使用 Pinia

在组件中通过useUserStore获取仓库实例,直接使用状态和方法。

<script setup> import { useUserStore } from '@/stores/user' // 获取仓库实例 const userStore = useUserStore() // 调用仓库方法 const handleLogin = async () => { await userStore.login({ username: 'zhangsan', password: '123' }) } </script> <template> <div v-if="userStore.isLogin()"> <p>用户名:{{ userStore.userInfo?.name }}</p> <button @click="userStore.logout">退出登录</button> </div> <button v-else @click="handleLogin">登录</button> </template>

5.Action异步写法

Pinia 的Action支持异步操作(直接写async/await),无需像 Vuex 那样区分同步 / 异步。

// src/stores/article.jsexportconstuseArticleStore=defineStore('article',()=>{constarticleList=ref([])// 异步Action:请求文章列表constfetchArticleList=async()=>{constres=awaitfetch('https://api.example.com/article/list')constdata=awaitres.json()articleList.value=data.list}return{articleList,fetchArticleList}})

6.storeToRefs:解构响应式状态

直接解构 Pinia 仓库的状态会丢失响应式,storeToRefs可以保留响应式。

<script setup> import { useUserStore } from '@/stores/user' import { storeToRefs } from 'pinia' // 引入storeToRefs const userStore = useUserStore() // 解构响应式状态 const { userInfo, token } = storeToRefs(userStore) // 方法直接解构(无需storeToRefs) const { login, logout } = userStore </script>

7. Pinia 持久化:状态本地存储

Pinia 默认不会持久化状态(刷新后丢失),可以用pinia-plugin-persistedstate插件实现本地存储。

步骤 1:安装插件

npminstallpinia-plugin-persistedstate

步骤 2:注册插件

// main.jsimport{createApp}from'vue'import{createPinia}from'pinia'importpiniaPluginPersistedstatefrom'pinia-plugin-persistedstate'// 引入插件importAppfrom'./App.vue'constpinia=createPinia()pinia.use(piniaPluginPersistedstate)// 注册插件createApp(App).use(pinia).mount('#app')

步骤 3:开启仓库持久化

// src/stores/user.jsexportconstuseUserStore=defineStore('user',()=>{// ...状态和方法},{persist:true// 开启持久化})

三、注意

想要了解更多有关Pinia的请点击这个链接到官网学习
想要学习持久化插件的更多内容的请点击这个链接

http://www.jsqmd.com/news/135795/

相关文章:

  • GPT-SoVITS能否用于历史人物声音复原?学术探讨
  • 热门DeepSeek推广公司大全(2025年12月更新) - 品牌2025
  • SaaS软件在中国市场的空间?小微创业者从事SaaS是否是死亡之路?
  • PCIe-1 DW 的 Read Request
  • 微信小程序帅帅音乐播放器网站系统有论文
  • 福州市哪里能开病假条诊断证明?
  • 微信小程序uniapp+vue在线答疑问答app
  • 【教程4>第10章>第8节】基于FPGA的图像高斯滤波开发——RGB彩色图像高斯滤波仿真测试以及MATLAB辅助验证
  • PCIe-SoC角度来看Memory Read Request
  • 微信小程序新生入学体验预约报道-学费缴纳系统
  • 每日反思(2025年12月24号)
  • 如何在数字化世界中找到自我
  • 某手深夜直播沦陷!黑灰产疯狂搞事的下场,给所有技术人提个醒
  • 云南昆明/南宁/海南海口商场外观美陈包装升级设计公司【力荐】
  • Linux操作系统之文件IO
  • 火山引擎智能3D视频启动商业化,计划落地直播应用
  • 迷宫生成算法:从生成树到均匀随机,再到工程化 Python 实现
  • Java毕设项目推荐-基于SpringBoot+Vue的医院管理系统设计与实现基于SpringBoot+Vue技术的医院运营管理系统的设计与实现【附源码+文档,调试定制服务】
  • 现代密码学【4】之计算安全性安全规约证明对称加密的窃听不可区分实验
  • 【新手学网安】不知从何下手?这篇干货给你安排得妥妥当当
  • 2025年12月石墨烯电地暖可靠品牌推荐榜 - 场景适配选型 - 优质品牌商家
  • 2025年论文保姆级攻略:10款降ai率工具深度实测
  • 1 小时速通!手把手教你从零搭建 Astro 博客并上线
  • DAY35复习日:类的装饰器
  • 推荐几家好点的DeepSeek推广公司(2025年12月更新) - 品牌2025
  • 零基础学网络安全 / 黑客:超详细入门教程,看完这一篇直接通关
  • 完整教程:Ubuntu 22.04 部署 CUDA 12.5 + NVIDIA 驱动 555 + Docker 容器化 GPU 环境
  • 38、TCP网络编程
  • C#基础语言练习--排序列表、File文件读写操作、FileStream文件流、二进制数据读写操作
  • 鸿蒙应用开发之用户首选项(Preferences)使用