【Pinia】Pinia的概念、优势及使用方式

学习公司的项目,发现用到了Pinia,于是上网学习了一下,发现了一篇比较优秀的文章,于是将极少部分放到此记录学习,原文链接在末尾。

是什么

官网解释:

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。

从上面官网的解释不难看出,pinia和Vuex的作用是一样的,它也充当的是一个存储数据的作用,存储在pinia的数据允许我们在各个组件中使用。

相较于vuex的优点

●Vue2和Vue3都支持,这让我们同时使用Vue2和Vue3的小伙伴都能很快上手。

●pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受小伙伴们的待见,pinia直接抛弃它了,这无疑减少了我们工作量。

●pinia中action支持同步和异步

●良好的Typescript支持,毕竟我们Vue3都推荐使用TS来编写,这个时候使用pinia就非常合适了

●无需再创建各个模块嵌套了,Vuex中如果数据过多,我们通常分模块来进行管理,稍显麻烦,而pinia中每个store都是独立的,互相不影响。

●体积非常小,只有1KB左右。 ●pinia支持插件来扩展自身功能。 ●支持服务端渲染。

使用

安装

复制代码
yarn add pinia
//或者使用 npm
npm install pinia

挂载

ts 复制代码
// main.ts


import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia();


const app = createApp(App);
app.use(pinia);
app.mount("#app");

创建某一模块相关的store

ts 复制代码
/src/store/user.ts


import { defineStore } from 'pinia'


// 第一个参数是应用程序中 store 的唯一 id
export const useUsersStore = defineStore('users', {
  // 其它配置项
})

创建store很简单,调用pinia中的defineStore函数即可,该函数接收两个参数:

●name:一个字符串,必传项,该store的唯一id。

●options:一个对象,store的配置项,比如配置store内的数据,修改数据的方法等等。

我们可以定义任意数量的store,因为我们其实一个store就是一个函数,这也是pinia的好处之一,让我们的代码扁平化了,这和Vue3的实现思想是一样的。

使用该store

ts 复制代码
/src/App.vue

<script setup lang="ts">
import { useUsersStore } from "../src/store/user";
const store = useUsersStore();
console.log(store);
</script>

使用store很简单,直接引入我们声明的useUsersStore 方法即可,我们可以先看一下执行该方法输出的是什么:

添加state

我们需要存放的数据就放在options对象中的state属性内。

假设我们往store添加一些任务基本数据,修改user.ts代码。

ts 复制代码
/src/store/user.ts

import { defineStore } from 'pinia'


export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
});

读取state

修改App.vue,通过解构赋值拿取数据,并让这几个数据显示出来。

注意:需要利用pinia的storeToRefs函数,将state中的数据变为响应式。

ts 复制代码
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <p>姓名:{{ name }}</p>
  <p>年龄:{{ age }}</p>
  <p>性别:{{ sex }}</p>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useUsersStore } from "../src/store/user";
import { storeToRefs } from 'pinia';
const store = useUsersStore();
const { name, age, sex } = storeToRefs(store);
</script>

结果:

修改state

ts 复制代码
<template>
  <h1>我是child组件</h1>
  <p>姓名:{{ name }}</p>
  <p>年龄:{{ age }}</p>
  <p>性别:{{ sex }}</p>
  <button @click="changeName">更改姓名</button>
</template>
<script setup lang="ts">
import { useUsersStore } from "../src/store/user";
import { storeToRefs } from 'pinia';
const store = useUsersStore();
const { name, age, sex } = storeToRefs(store);
const changeName = () => {
  store.name = "小猪课堂";
};
</script>

重置state

有时候我们修改了state数据,想要将它还原,比如用户填写了一部分表单,突然想重置为最初始的状态。

ts 复制代码
<button @click="reset">重置store</button>
// 重置store
const reset = () => {
  store.$reset();
};

批量更改state数据

ts 复制代码
store.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.hasChanged = true
})

替换整个state

ts 复制代码
store.$state = { counter: 666, name: '张三' }

添加getter

ts 复制代码
export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
  getters: {
    getAddAge: (state) => {
      return state.age + 100;
    },
  },
});

使用getter

ts 复制代码
<template>
  <p>新年龄:{{ store.getAddAge }}</p></template>
<script setup lang="ts">
import { useUsersStore } from "../src/store/user";
const store = useUsersStore();
</script>

直接在标签上使用了store.gettAddAge方法,这样可以保证响应式

getter中调用其它getter

ts 复制代码
export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
  getters: {
    getAddAge: (state) => {
      return state.age + 100;
    },
    getNameAndAge(): string {
      return this.name + this.getAddAge; // 调用其它getter
    },
  },
});

getter传参

ts 复制代码
export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
  getters: {
    getAddAge: (state) => {
      return (num: number) => state.age + num;
    },
    getNameAndAge(): string {
      return this.name + this.getAddAge; // 调用其它getter
    },
  },
});
html 复制代码
 <p>新年龄:{{ store.getAddAge(1100) }}</p>

添加actions

ts 复制代码
export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
    actions: {
    saveName(name: string) {
      this.name = name;
    },
  },
});

使用actions

ts 复制代码
//app.vue
const saveName = () => {
  store.saveName("我是小猪");
};

汇总代码

main.ts代码:

ts 复制代码
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia();


const app = createApp(App);
app.use(pinia);
app.mount("#app");

user.ts代码:

ts 复制代码
import { defineStore } from "pinia";


// 第一个参数是应用程序中 store 的唯一 id
export const useUsersStore = defineStore("users", {
  state: () => {
    return {
      name: "小猪课堂",
      age: 25,
      sex: "男",
    };
  },
  getters: {
    getAddAge: (state) => {
      return (num: number) => state.age + num;
    },
    getNameAndAge(): string {
      return this.name + this.getAddAge; // 调用其它getter
    },
  },
  actions: {
    saveName(name: string) {
      this.name = name;
    },
  },
});

App.vue代码:

ts 复制代码
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <p>姓名:{{ name }}</p>
  <p>年龄:{{ age }}</p>
  <p>性别:{{ sex }}</p>
  <p>新年龄:{{ store.getAddAge(1100) }}</p>
  <p>调用其它getter:{{ store.getNameAndAge }}</p>
  <button @click="changeName">更改姓名</button>
  <button @click="reset">重置store</button>
  <button @click="patchStore">批量修改数据</button>
  <button @click="saveName">调用aciton</button>


  <!-- 子组件 -->
  <child></child>
</template>
<script setup lang="ts">
import child from "./child.vue";
import { useUsersStore } from "../src/store/user";
import { storeToRefs } from "pinia";
const store = useUsersStore();
const { name, age, sex } = storeToRefs(store);
const changeName = () => {
  store.name = "张三";
  console.log(store);
};
// 重置store
const reset = () => {
  store.$reset();
};
// 批量修改数据
const patchStore = () => {
  store.$patch({
    name: "张三",
    age: 100,
    sex: "女",
  });
};
// 调用actions方法
const saveName = () => {
  store.saveName("我是小猪");
};
</script>

原文:
大菠萝!这一次彻底搞懂Pinia!(保姆级教程)

相关推荐
进取星辰16 分钟前
28、动画魔法圣典:Framer Motion 时空奥义全解——React 19 交互动效
前端·react.js·交互
不爱吃饭爱吃菜1 小时前
uniapp微信小程序-长按按钮百度语音识别回显文字
前端·javascript·vue.js·百度·微信小程序·uni-app·语音识别
程序员拂雨2 小时前
Angular 知识框架
前端·javascript·angular.js
GoodStudyAndDayDayUp2 小时前
gitlab+portainer 实现Ruoyi Vue前端CI/CD
前端·vue.js·gitlab
程序员阿明2 小时前
vite运行只能访问localhost解决办法
前端·vue
前端 贾公子2 小时前
uniapp -- 验证码倒计时按钮组件
前端·vue.js·uni-app
zhengddzz2 小时前
从卡顿到丝滑:JavaScript性能优化实战秘籍
开发语言·javascript·性能优化
淡笑沐白2 小时前
AJAX技术全解析:从基础到最佳实践
前端·ajax
Go_going_2 小时前
ajax,Promise 和 fetch
javascript·ajax·okhttp
龙正哲3 小时前
如何在Firefox火狐浏览器里-安装梦精灵AI提示词管理工具
前端·firefox