Vue3(ts)中使用 pinia

什么是pinia?

Pinia 最初是在 2019 年 11 月左右重新设计使用 Composition API,可以理解为下一代 vuex,作者也称之为vuex5,同时vue已经将 pinia 收入 官方账户了

名字的由来

Pinia (发音为 /piːnjʌ/,类似英文中的 "peenya") 是最接近有效包名 piña (西班牙语中的 pineapple,即"菠萝") 的词。 菠萝花实际上是一组各自独立的花朵,它们结合在一起,由此形成一个多重的水果。 与 Store 类似,每一个都是独立诞生的,但最终它们都是相互联系的。 它(菠萝)也是一种原产于南美洲的美味热带水果。

为什么要用它?比vuex 强在哪里

pinia 最开始是一个实验,其目的是设计一个拥有组合式 API 的 Vue 状态管理库,来弥补vuex 的不足,且同时满足 vue2和vue3,下图是 pinia作者 总结的五点

  • 1 同时支持 options(vue2)和composition api(vue3)
  • 2 仅保留 state getters actions(取消了vuex 中 Mutation)
  • 3 取消嵌套模块(取消了vuex 中 Module)
  • 4 支持ts
  • 5 透明 自动化的代码拆分

实际应用

项目创建 vite + vue3 + pinia

执行命令 npm create vite@latest 或 yarn create vite

sql 复制代码
yarn create vite
// 或者npm create vite@latest  

按照提示 输入项目名称、框架类型(必须是vue,因为pinia 只支持vue)、TypeScript

安装 pinia

csharp 复制代码
yarn add pinia

挂载

打开main.ts

javascript 复制代码
import { createPinia } from 'pinia'

const pinia = createPinia()

const app = createApp(App)

app.use(pinia)

初始化 定义 Store

src 目录下 创建 index.ts

写法一 类似于 vuex的写法 没有mutations

user为容器(可以理解为命名空间)

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

export const userStore = defineStore('user', {
  state: () => {
    return {
      name: 'iwhao',
      age: 18,
      count: 1,
    }
  },
  getters: {
    countDouble: (state) => {
      return state.count * 2
    }
  },
  actions: {
    countAdd() {
      this.count++
    }
  }
})

写法二 composition api pinia 会自动识别 ref类型的 为 state 、computed类型的为 getter、function 为 action

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

export const userStore = defineStore('user', () => {
  const name = ref('iwhao')
  const age = ref(18)
  const count = ref(1)
  const countDouble = computed(() => count.value * 2)
  function countAdd() {
    count.value++
  }
  return { name, age, count, countDouble, countAdd }
})

使用

引用

这里直接在项目中components下的HelloWorld.vue 中写入案列

xml 复制代码
<template>
  <p>name: {{ user.name }}</p>
  <p>age: {{ user.age }}</p>
  <p>count: {{ user.count }}</p>
  <p>countDouble: {{ user.countDouble }}</p>
  <button @click="user.countAdd()">增加</button>
</template>
<script setup lang="ts">
    import { userStore } from "../store/index";
    const user = userStore();
</script>

效果如下

注意

不要直接解构使用,例如下方代码,因为这种写法 name, age, count, countDouble 将不会是响应式

css 复制代码
...
    <p>name: {{ user.name }}</p>
    <p>age: {{ user.age }}</p>
    <p>count: {{ user.count }}</p>
    <p>countDouble: {{ user.countDouble }}</p>
    <button @click="user.countAdd()">增加</button>
    <br />
    <p>name: {{ name }}</p>
    <p>age: {{ age }}</p>
    <p>count: {{ count }}</p>
    <p>countDouble: {{ countDouble }}</p>
    <button @click="user.countAdd()">增加</button>
...
const user = userStore();
const { name, age, count, countDouble } = user;

那如何让解构出来的变量 变成响应式呢,需要引入 storeToRefs

javascript 复制代码
import { storeToRefs } from "pinia";

const { name, age, count, countDouble } = storeToRefs(user);

更新

第一种方法(不推荐,如果只是单变量更新的话无所谓)

ini 复制代码
...
 <button @click="upUser">更新</button>
...
const upUser = () => {
  user.name = '张三'
  user.age = 20
  user.count = 100
}

如果批量更新多个,推荐使用 $patch

ini 复制代码
...
  <button @click="upUserBath">批量更新</button>
...
const upUserBath = () => {
  user.$patch({
    name: "张三",
    age: 20,
    count: 100,
  });
};
// 或 这种写法
const upUserBath = () => {
  user.$patch((state) => {
    state.name = "张三";
    state.age = 20;
    state.count = 100;
  });
};
相关推荐
PandaCave7 分钟前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
软件小伟9 分钟前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾30 分钟前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧39 分钟前
TypeScript 的发展与基本语法
前端·javascript·typescript
chusheng18401 小时前
Java项目-基于SpringBoot+vue的租房网站设计与实现
java·vue.js·spring boot·租房·租房网站
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
游走于计算机中摆烂的1 小时前
启动前后端分离项目笔记
java·vue.js·笔记
幼儿园的小霸王2 小时前
通过socket设置版本更新提示
前端·vue.js·webpack·typescript·前端框架·anti-design-vue
疯狂的沙粒2 小时前
对 TypeScript 中高级类型的理解?应该在哪些方面可以更好的使用!
前端·javascript·typescript
码蜂窝编程官方2 小时前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游