pinia基本使用介绍

写在前面

之前我们一直使用的状态管理都是vuex或者是基本的provide和inject,因为技术在更新,所以,一些人就闲不住,就开始倒腾新技术了,不然卷不动了啊,怎么拉开与别人的差距呢?那么今天的技术知识点就是我们今天要说的pinia,新一代全局状态管理,

pinia是什么

pinia直接理解为vuex的新版本也不能说是错的,但是他又是一个全新的知识点,所以如果非要说他是什么,他就是一个新版的全局状态管理方案,所谓的全局状态的管理就是一个项目中在不同的组件中可以同时同步某一个数据的过程。我说他是一个vuex5的版本其实不算错,毕竟官网有结合了 Vuex 5 核心团队讨论中的许多想法这样一句话。

相比之前的解决方案优势是什么

之前的解决方案还是比较多的,

  • 缓存处理方案

比如开始的时候我们可以使用缓存进行同步数据,虽然很low但是它确实属于一种方案,但是这种方案的实时性很差,也就是很难做到信息的及时同步,虽然你可以写很多监听来达到一个同步的效果,但是代码维护起来就会很笨重

  • provide/inject

这种方案是可以解决缓存解决不了的问题,但是他只适应于小项目,因为他不太容易模块化进行处理数据,如果所有的数据都挂载到根结点上,那么后期的代码会很臃肿,无法模块化处理就意味着他很难适用大项目,不过项目我还是推荐使用的。

  • vuex

这个就是神一样的存在的解决方案,上面的痛点都没有,但是有一个比较大的缺点就是他的解决方案很完美,不过小项目中使用会显的很笨重,同时它提供的mutation和action其实都可以处理数据,但是偏偏将同步和异步分开了,我个人一直觉得mutation完全没有必要存在,所以他在大型项目中可以进行模块化的管理,小项目中使用略显笨重,这个一般都是根据实际情况进行使用

  • pinia

所有的新技术出来都是为了解决之前的痛点,pinia的优势就是我上面说的三种的劣势他都完美的解决了,所以我们还是很有必要学习一下的,具体罗列一下有点吧:

  • 小巧 压缩之后才1KB
  • 完美支持Ts (虽然我不太喜欢)
  • 支持插件扩展自身功能
  • 抛弃了mutation的使用,直接一个action搞定(早就该这样了)
  • 支持服务端渲染 (虽然我不咋用)
  • 无需创建各个模块嵌套,它本身的store就是独立的
  • 还支持vue2的版本
  • 在不重新加载页面的情况下修改您的 Store 在开发时保持任何现有状态(这个就很牛逼了,之前这个不实现的时候开发过程很痛苦)

我这个人其实不怎么喜欢接触新的东西,我觉得旧的可以用的话,将旧的用到极致也很不错,一只使用新的,不见得是一件好事,不过这样显的我很不好学一样,不说了,我们开始学习。

使用pinia

官网

  • 安装
yarn add pinia
  • 挂载全局到main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
  • 创建store

pinia提供了defineStore()方法进行创建sotre,这个store就和vuex中的一样,用来存储我们需要全局管理的一些数据

import { defineStore } from 'pinia'
export const useUserStore = defineStore('main', {})
  • 引入使用
import { useUserStore } from "./store/user";
const useStore = useUserStore();
console.log(useStore); //Proxy {$id: 'main', $onAction: ƒ, $patch: ƒ, $reset: ƒ, $subscribe: ƒ, …}
  • 数据存储state
// state是一个函数,返回是一个对象
import { defineStore } from 'pinia'
export const useUserStore = defineStore('main', {
    state: () => {
        return {
            loginName: 'Kim',
            loginTime: new Date(),
            age : 18
        }
    }
})
  • 获取数据
<script setup>
  import { ref } from "vue";
  import { useUserStore } from "./store/user";
  const useStore = useUserStore();
  console.log(useStore); //Proxy {$id: 'main', $onAction: ƒ, $patch: ƒ, $reset: ƒ, $subscribe: ƒ, …}
  const loginName = useStore.loginName;
  const age = useStore.age;
  const age = ref(useStore.age);
</script>
 <h4>{{ loginName }}</h4>
 <h4>{{ loginTime }}</h4>
 <h4>{{ age }}</h4>
<!-- 当然你可以直接将store里面的数据获取出来,不用解构也是可以的,默认的就是带有响应式的 -->
 <h4>{{ useStore.loginName }}</h4>
 <h4>{{ useStore.loginTime }}</h4>
 <h4>{{ useStore.age }}</h4>
  • 修改数据
<button @click="changeStoreValue">更新store的value</button>
const changeStoreValue = () => {
  console.log("passing");
  useStore.loginName = "Jim";
  useStore.loginTime = "890";
};

这个时候会发现数据并没有变化,这是因为我们没有使用pinia提供的支持数据响应式的方法,所以我们需要这样进行取值

import { storeToRefs } from "pinia";
const { loginName, age } = storeToRefs(useStore);

这个时候会发现,数据就发生了变化,这里会发现,如果我们使用vue3自己提供的ref将变量改为响应式的话,是不是可以呢?自己可以试试,是不行的。

  • 批量更改store的值
<button @click="patchStoreValue">批量更改store的value</button>
//批量更改store的值
const patchStoreValue = () => {
  useStore.$patch({
    loginName: "mary",
    age: 20,
  });
};
  • 重置store
<button @click="resetStoreVla">重置store</button>
//重置store
const resetStoreVla = () => {
  useStore.$reset();
};
  • getter

如果你之前使用vuex比较多的话,就对这个getter应该不会陌生, 其实他就是vue组件中的computed,我在别的文章里面不止一次的说过这个计算属性,这里就不做赘述了,这里简单的说一下他的用法

import { defineStore } from 'pinia'
export const useUserStore = defineStore('main', {
    state: () => {
        return {
            loginName: 'Kim',
            loginTime: new Date(),
            age: 18
        }
    },
  // 相当于计算属性 自带的有响应式,所以这里获取值的时候 不需要担心解构或者ref等问题
    getters: {
        completeName: (state) => {
            return `name is ${state.loginName}`
        },
    }
})

写法二:

       //不使用箭头函数的时候 使用this也是可以的,因为this指向的就是当前的store
        completeName(state) {
            return `name is ${this.loginName}`
        },
  • 获取getter的数据
    <h4>{{ useStore.completeName }}</h4>
  • Getter 中使用其他getter

直接使用即可,将getter当做一个变量就可以了

getters: {
        completeName(state) {
            return `name is ${this.loginName}`
        },
        otherGetter() {
            return this.completeName + 'ShowOther'
        }
    }
  • actions
import { defineStore } from 'pinia'
export const useUserStore = defineStore('main', {
    actions: {
        setName(name:String) {
            this.loginName = name
        }
    }
})
  • 使用actions
<input type="text" v-model="data.name" id="" />
<button @click="setNameV">设置名字</button>
const setNameV = () => {
  useStore.setName(data.name);
};
总结

总体下来基本的使用还是非常简单的,和vuex相比是简单的很多了,在加上新版本的vue的组合式api的写法,之前可能比较复杂的功能代码量也会很少,所以个人还是比较推荐使用pinia的。

写到后面

关于pinia的这里就写这么多了,后续项目中使用的时候遇到的一些比较棘手的问题的以后我会持续记录的,有兴趣的或者觉得我写的哪里不对的,可以直接私信我或者是下方留言,我看到了都会回复的,另外就是我只是看的官网和别人的一些帖子,所以写的都是一些比较基础的用法,加上只是演示的demo,所以也不会写的那么复杂,不要纠结!

### 如何在 Vue 3 项目中使用 TypeScript 和 Pinia #### 安装依赖 为了在一个新的 Vue 3 项目中集成 Pinia 并启用 TypeScript 支持,需先安装必要的包。假设已经创建好了一个基于 Vue CLI 或 Vite 的新项目,则可以通过如下命令来添加所需依赖: ```bash npm install pinia @pinia/nuxt vue-demi ``` 对于已有项目的升级操作同样适用上述指令。 #### 设置 Store 文件夹结构 通常会在 `src` 下建立名为 `stores` 的文件夹用于存放所有的 store 模块定义[^1]。下面是一个典型的例子展示如何构建一个简易的任务列表应用对应的 store 结构: ```typescript // src/stores/taskStore.ts import { defineStore } from "pinia"; export const useTaskStore = defineStore({ id: 'task', state: () => ({ tasks: [] as string[], }), actions: { addTask(taskName:string){ this.tasks.push(taskName); }, removeTask(index:number){ this.tasks.splice(index, 1); } } }); ``` 这段代码展示了怎样利用组合式 API 来声明状态(`state`)以及修改这些状态的方法(`actions`). 同时可以看到类型注解使得整个过程更加直观易懂. #### 主程序入口处引入 Pinia 插件 为了让应用程序能够访问到之前定义好的 stores,在 main.js(main.ts) 中需要做相应的设置以便让插件生效: ```javascript // main.ts import { createApp } from 'vue'; import App from './App.vue'; import { createPinia } from 'pinia'; const app = createApp(App); app.use(createPinia()); app.mount('#app'); ``` 此部分确保了所有组件都可以轻松获取到由 Pinia 提供的服务和功能. #### 组件内部调用 Store 方法 最后一步是在具体业务逻辑所在的组件里边去实际运用我们刚刚准备完毕的数据存储设施. 这里给出一段示范性的模板说明应该如何完成这项工作: ```html <template> <div class="tasks"> <ul v-for="(item,index) of taskList" :key="index">{{ item }}</ul> <input type="text" placeholder="Enter new Task..." v-model.trim="newItem"/> <button @click="addNew">Add</button> </div> </template> <script lang="ts"> import { computed, ref } from 'vue' import { useTaskStore } from '../stores/taskStore' export default { name:'TasksComponent', setup(){ let newItem=ref(''); const taskStorage =useTaskStore(); function addNew() { if(newItem.value.length>0){ taskStorage.addTask(newItem.value); newItem.value=''; } } return{ taskList:computed(() => taskStorage.tasks), newItem, addNew }; } } </script> ``` 以上就是完整的流程介绍,从环境搭建直到最终实现基本的功能交互.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦秸垛的守望者

阅读就是对我最大的支持,感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值