走进Pinia的世界

1,216 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

Pinia是什么

在vue2等版本,我们使用全局的状态管理工具都是vuex,当我们使用vue3时,Pinia便开始展露头角,那Pinia是什么呢? 其实Pinia和Vuex别无二致,都是全局或者跨组件之间共享状态。但是Pinia并不是Vue3专属,Vue2也同样适用。它有以下且更多的优点:

  • 删除了mutations
  • 热模块更换
  • 完美的ts支持
  • 可以使用插件扩展Pinia的功能

Vue结合Pinia

yarn add pinia

安装好之后需要创建一个根存储同时在入口文件中传递给程序:

import { createApp } from 'vue'
import {createPinia} from 'pinia'
createApp(App).use(createPinia())

我们把存储数据状态的文件称为Store,且这个Store是可以被全局访问的。它有三个概念,stategetteractions,是不是比vuex少了一个mutation

定义一个Store

定义一个Store需要借助defineStore进行定义,第一个参数作为Store唯一的id,第三个参数是一个对象,里面包含了上面说到的stategetteractions等。 我们以官网的例子来说明:

import { defineStore } from "pinia";

export const todoList = defineStore('todoList', {
    state: () => ({ // state是定义数据的地方,是一个函数,并返回一个对象
        todos: [],//这个是一个Array类型变量
        filter: 'all',//这个是数据的状态
        
        nextId: 0,//这个用于存储数据的id
    }),
    getters: {  //getter有点类似于计算属性
        finishedTodos(state) { // 这个用于过滤出完成状态的数据
            return state.todos.filter((todo) => todo.isFinished)
        },
        unfinishedTodos(state) { // 这个用于过滤出没有完成的数据
            return state.todos.filter((todo) => !todo.isFinished)
        },
        filteredTodos(state) { // 这个则是上面两个getter的结合,根据filter判断返回不同的结果
            if (this.filter === 'finished') {
                // 自动调用其他 getter ✨
                return this.finishedTodos
            } else if (this.filter === 'unfinished') {
                return this.unfinishedTodos
            }
            return this.todos
        },
    },
    actions: { // actions和vuex里面的actions差不多,只是pinia的可以直接操作state,而vuex需要将数据commit到mutation再到state
        // 任何数量的参数,返回一个 Promise 或者不返回
        addTodo(text) { // 这个就是将textpush进行todo数组
            // 你可以直接改变状态
            this.todos.push({ text, id: this.nextId++, isFinished: false })
        },
    },
})

我们在vue组件里面使用:

import { useTodoListStore } from '../store';
const todoList = useTodoListStore();
console.log(todoList) 

我们这里打印一下,

a.png

打印出来的就是一个proxy,还有一些数据源,和在getteractions定义的方法都能找到。我们使用addTodo注入数据,同时调用unfinishedTodos打印一下会不会成功?

import { useTodoListStore } from '../store';
const todoList = useTodoListStore();
console.log(todoList)
todoList.addTodo("第一个数据");
console.log(todoList.unfinishedTodos)

b.png

说明Pinia创建成功!!!