了解Pinia:Vue.js的新一代状态管理库

引言

在Vue.js开发中,状态管理是一个重要的问题。为了更好地管理应用程序的状态,开发者们通常会使用Vuex。然而,随着Vue 3的发布,一个新的状态管理库Pinia也逐渐崭露头角。本文将深入介绍Pinia的使用方式,并与Vuex进行比较,以帮助开发者更好地理解和选择适合自己项目的状态管理库。

为什么要使用pinia?

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。 如果您熟悉 Composition API,您可能会认为您已经可以通过一个简单的 export const state = reactive({}). 这对于单页应用程序来说是正确的,但如果它是服务器端呈现的,会使您的应用程序暴露于安全漏洞。 另外:即使在小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处:

  • dev-tools 支持

    • 跟踪动作、突变的时间线
    • Store 出现在使用它们的组件中
    • time travel 和 更容易的调试
  • 热模块更换

    • 在不重新加载页面的情况下修改您的 Store
    • 在开发时保持任何现有状态
  • 插件:使用插件扩展 Pinia 功能

  • 为 JS 用户提供适当的 TypeScript 支持或 autocompletion

  • 服务器端渲染支持

安装和配置

  1. 使用你所常用的包管理器进行安装
sh 复制代码
yarn add pinia
# 或者使用 npm
npm install pinia
  1. 在应用程序中注册store:在Vue应用程序的入口文件中使用createPinia函数创建一个Pinia实例,并将其作为插件注册到Vue应用程序中。
js 复制代码
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')

核心用法

1. 定义Store

首先,我们需要定义一个Store来管理应用程序的状态。一个Store是一个包含了state、getters、mutations和actions等属性和方法的对象。可以通过创建一个类来定义Store,然后使用defineStore函数将其转换为Pinia Store。

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

// useMyStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useMyStore = defineStore('myStore', {
  state: () => ({
    count: 0,
  }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++;
    },
  },
});

这个 name ,也称为 id ,是必要的,Pinia 使用它来将 store 连接到 devtools。 将返回的函数命名为 use... 是跨可组合项的约定,以使其符合你的使用习惯。

2. 创建和使用Store

在Vue组件中,可以通过useStore函数来创建和使用我们定义的Store。

javascript 复制代码
import { useMyStore } from './my-store';

export default {
  setup() {
    const store = useMyStore();

    return {
      // 您可以返回整个 store 实例以在模板中使用它
      store,
    };
  },
};

您可以根据需要定义任意数量的 store ,并且您应该在不同的文件中定义每个 store以充分利用 pinia(例如自动允许您的包进行代码拆分和 TypeScript 推理)。

3. 访问State和Getters

在组件中,可以通过访问store对象来获取state和getters。

javascript 复制代码
export default {
  setup() {
    const store = useMyStore();

    console.log(store.count); // 访问state
    console.log(store.doubleCount); // 访问getter
    
    // ❌ 这不起作用,因为它会破坏响应式
    // 这和从 props 解构是一样的, count的值不会变化
    const { count } = store

    return {
      store,
    };
  },
};

为了从 Store 中提取属性同时保持其响应式,您需要使用storeToRefs()。 它将为任何响应式属性创建 refs。 当您仅使用 store 中的状态但不调用任何操作时,这很有用!

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

export default {
  setup() {
    const store = useMyStore();

    console.log(store.count); // 访问state
    console.log(store.doubleCount); // 访问getter
    
    const { count, doubleCount } = storeToRefs(store)

    return {
      count,
      doubleCount,
      store,
    };
  },
};

大多数时候,getter 只会依赖状态,但是,他们可能需要使用其他 getter。 正因为如此,我们可以在定义常规函数时通过 this 访问到 整个 store 的实例

4. 调用Actions

在组件中,可以通过调用store对象的actions来执行一些异步操作或者修改state。

javascript 复制代码
export default {
  setup() {
    const store = useMyStore();

    store.increment(); // 调用action

    return {
      store,
    };
  },
};

Actions 相当于组件中的 methods。 它们可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑

5. 使用插件

Pinia还支持使用插件来扩展其功能。可以通过use函数来使用插件。

javascript 复制代码
import { useMyStore } from './my-store';
import { myPlugin } from './my-plugin';

export default {
  setup() {
    const store = useMyStore();

    store.use(myPlugin); // 使用插件

    return {
      store,
    };
  },
};

与Vuex相比

与Vuex相比,Pinia具有以下优点:

1. 更好的类型推断 :Pinia使用了Vue 3的Composition API,可以更好地推断出store中的状态、操作和getter的类型。 2. 更好的性能 :Pinia使用了Vue 3的响应式系统,可以更高效地追踪状态的变化,并且只在需要时更新相关组件。 3. 更简洁的代码 :相比Vuex,使用Pinia可以写出更简洁、可读性更高的代码。 4. 更好的扩展性:Pinia支持模块化和插件机制,可以轻松地扩展和组织store。

然而,与Vuex相比,Pinia也存在一些缺点:

1. 生态系统相对较小:由于是一个相对较新的库,与Vuex相比,Pinia在生态系统方面可能还不够成熟。

总结

Pinia是一个简单、直观且性能优越的Vue.js状态管理库。通过使用Vue 3的Composition API,Pinia提供了更好的类型推断和更好的性能。与Vuex相比,Pinia具有更简洁的代码和更好的扩展性。然而,学习曲线较陡峭和生态系统相对较小是其缺点。在选择状态管理库时,开发者可以根据项目需求和团队经验来选择适合自己的库。

相关推荐
心在飞扬13 分钟前
ReRank重排序提升RAG系统效果
前端·后端
心在飞扬18 分钟前
RAPTOR 递归文档树优化策略
前端·后端
前端Hardy35 分钟前
别再无脑用 `JSON.parse()` 了!这个安全漏洞你可能每天都在触发
前端·javascript·vue.js
前端Hardy37 分钟前
别再让 `console.log` 上线了!它正在悄悄拖垮你的生产系统
前端·javascript·vue.js
青青家的小灰灰41 分钟前
从入门到精通:Vue3 ref vs reactive 最佳实践与底层原理
前端·vue.js·面试
OpenTiny社区1 小时前
我的新同事是个AI:支持skill后,它用TinyVue搭项目还挺溜!
前端·vue.js·ai编程
心在飞扬1 小时前
MultiVector 多向量检索
前端·后端
用户39051332192881 小时前
async 函数返回的 Promise 状态何时变为 resolved
前端
李剑一1 小时前
大屏天气展示太普通?视觉升级!用 Canvas 做动态天气遮罩,雷阵雨效果直接封神
前端·vue.js·canvas
Lee川2 小时前
现代Web开发中的CSS继承、Flexbox布局与LocalStorage交互:从文档解析到实践应用
前端·css