知识笔记(九十四)———vue3中的菠萝能吃吗?

发布时间:2024年01月22日

开个玩笑,这里说的菠萝不是吃的,是vue3中的状态管理器(pinia)

Vue3 Pinia使用


在学习 Vue2 的一定都知道,在 vue2 版本中,如果想要使用状态管理器,那么一定是集成 Vuex,首先说明一点,Vuex 在 vue3 项目中依旧是可以正常使用的,是 vue 项目的正规军。但是,今天我们学习一下菠萝,Pinia 目前也已经是 vue 官方正式的状态库。适用于 vue2 和 vue3。可以简单的理解成 Pinia 就是 Vuex5。也就是说, Vue3 项目,建议使用Pinia,当然很多公司或者是项目由 vue2 转为 vue3 之后,由于习惯了使用 vuex ,所以说,在 vue3 当中继续使用 vuex 的,也不是少数,都知道就可以,根据实际情况来选择。

首先先来了解一下

什么是 Pinia?

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。Pinia 的成功可以归功于他管理存储数据的独特功能,例如:可扩展性、存储模块组织、状态变化分组、多存储创建等。

Pinia 最初是为了探索 Vuex 的下一次迭代会是什么样子,结合了 Vuex 5 核心团队讨论中的许多想法。最终,意识到 Pinia 已经实现了我们在 Vuex 5 中想要的大部分内容,并决定实现它 取而代之的是新的建议。

现在官方网站的生态推荐已经将Vuex换成了Pinia

Pinia 的优点


Pinia 被 vue 纳入正规编制,肯定是有原因的,那 pinia 有啥优点呢,主要是一下几点:

pinia 符合直觉,易于学习。
pinia 是轻量级状态管理工具,大小只有1KB.
pinia 模块化设计,方便拆分。
pinia 没有 mutations,直接在 actions 中操作 state,通过 this.xxx 访问响应的状态,尽管可以直接操作 state,但是还是推荐在 actions 中操作,保证状态不被意外的改变。
store 的 action 被调度为常规的函数调用,而不是使用 dispatch 方法或者是 MapAction 辅助函数,这是在 Vuex 中很常见的。
支持多个 store。
支持 Vue devtools、SSR、webpack 代码拆分。

与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。

总结以下五点:

  1. 可以对Vue2和Vue3做到很好的支持,也就是老项目也可以使用Pinia。
  2. 抛弃了Mutations的操作,只有state、getters和actions.极大的简化了状态管理库的使用,让代码编写更加容易直观。
  3. 不需要嵌套模块,符合Vue3的Composition api ,让代码更加扁平化。
  4. 完整的TypeScript支持。Vue3版本的一大优势就是对TypeScript的支持,所以Pinia也做到了完整的支持。如果你对Vuex很熟悉的化,一定知道Vuex对TS的语法支持不是完整的(经常被吐槽)。
  5. 代码更加简洁,可以实现很好的代码自动分割。Vue2的时代,写代码需要来回翻滚屏幕屏幕找变量,非常的麻烦,Vue3的Composition api完美了解决这个问题。 可以实现代码自动分割,pinia也同样继承了这个优点。

如何使用Pinia?

搭建项目并安装Pinia,执行安装Pinia

yarn add pinia
// or
npm i pinia

首先在main.js中引入pinia

import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'//创建一个 pinia(根存储)并将其传递给应用程序:
createApp(App).use(createPinia()).mount('#app')

在src目录下创建一个store文件夹,并新建index.js,写入以下内容:

import { defineStore } from 'pinia'

// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {
? // other options...
? state: () => {
? ? return {
? ? ? msg: 'hello world!',
? ? ? count: 0
? ? }
? },
? getters: {},
? actions: {}
})

defineStore() 定义Store,并且它需要一个唯一名称,作为第一个参数传递

参数:

第一个参数:相当于为容器起一个名字。注意:这里的名字必须唯一,不能重复。

第二个参数:一个配置对象,里边是对容器仓库的配置说明。

state 属性: 用来存储全局的状态的

getters属性: 类似计算属性,用来监视或者说是计算状态的变化的,有缓存的功能。

actions属性: 修改state,对state里数据变化的业务逻辑,需求不同,编写逻辑不同

在组件中使用

两种方法

第一种:之间使用整个store取值

第二种:结构取值,但不要直接结构store

storeToRefs:为了从 Store 中提取属性同时保持其响应式, 它将为任何响应式属性创建 refs

实例:

<template>
? <div>{{ store.msg }}</div>
? <div>{{ msg }}</div>
</template>

<script setup>
import { useStore } from '@/store/index';
import { storeToRefs } from "pinia";
let store = useStore()
// 不要直接结构,会破坏响应式,使用storeToRefs
// const { msg } = store;
const { msg } = storeToRefs(store);
</script>

直接修改

<template>
? <div>{{ store.count }}</div>
? <button @click="add">+1</button>
</template>

<script setup>
import { useStore } from '@/store/index';
let store = useStore()
const add = () => {
? store.count++
}
</script>

调用$patch

这个方法可以修改多个状态

<template>
? <div>{{ store.count }}</div>
? <button @click="add">+1</button>
</template>

<script setup>
import { useStore } from '@/store/index';
let store = useStore()
const add = () => {
? store.$patch({
? ? count: store.count + 1,
? ? msg: 'hello pinia!'
? })
}
</script>

文章来源:https://blog.csdn.net/lrx276/article/details/135739331
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。