2023了,你还不会pinia吗?淦它!

261 阅读2分钟

介绍

在 Vue3 时代,我们使用 Pinia 作为我们的数据仓库,是因为 Vue3 建议我们使用 Composition API 代替之前的 Options API,而 Pinia 与之完美的融合

  1. 使用 pinia作为数据仓库,可以很方便的在多个 组件/页面 中共用同一个变量
  2. 对 TypeScript 的支持更加友好
  3. 可以在不重载页面的前提下修改仓库数据,且能实时响应在页面

Pinia和Vuex对比

  1. 抛弃了 mutations 的操作
  2. 对 TypeScript 的支持更加友好
  3. 抛弃了 module ,store 目录下的所有 .ts/.js 文件均是一个 pinia 模块
  4. 自动导入注册

使用过程

安装引入

要想使用 pinia, 首先需要安装对应依赖:

npm install pinia

然后在 main.js 中引入并使用

// main.js中引入 
const app = createApp(App); 
// vue使用pinia 
import { createPinia } from "pinia" 
app.use(createPinia());

定义store

在 src/store 目录下新建 .js/.ts 文件,一个文件即是一个 store,通过 defineStore 来定义仓库

  1. 第一个参数为一个 唯一标识
  2. 第二个参数为一个 optionoption 中有 state、getters、actions 三个字段,分别表示 指代这个仓库的 数据、计算属性、方法
import { defineStore } from 'pinia'; 

export const demoStore = defineStore('demo', { 
    state: () => { 
        return { 
            // 所有这些属性都将自动推断其类型 
            counter: 0, 
            mobile:"13111111111" 
        } 
     }, 
     getters:{}, 
     actions:{} 
})

渲染state

接下来我们在 页面 渲染 state

    <script setup> 
        // 引入定义的store 
        import { demoStore } from '@/store/demo'; 
        const store = demoStore(); 
    </script> 
    <template> 
        <div>{{ store.counter }}</div> 
    </template>

如果我们想直接渲染 counter 可以通过 storeToRefs 处理一下:

<script setup> 
    // 引入定义的store 
    import { demoStore } from '@/store/demo'; 
    // 引入storeToRefs函数,使得解构store仍具有响应式特性 
    import { storeToRefs } from "pinia"; 
    
    const store = demoStore(); 
    const { counter } = storeToRefs(store); 
</script> 
<template> 
    <div>{{ counter }}</div> 
</template>

修改state

修改 state 有四种方式,这里挨个来介绍一番:

一、直接修改

通过点击事件触发该 add 方法,直接操作 store.counter

const add = () => store.counter ++

二、$patch传递参数

通过点击事件触发该 add方法,通过 store.$patch 进行修改,参数是个 对象

const add = () => { 
    store.$patch({ 
        count:store.counter + 2, 
    }) 
};

三、$patch传递方法

通过点击事件触发该 add方法,通过 store.$patch 进行修改,参数是个 回调函数,可以在回调函数中处理

const add = () => { 
    store.$patch(state => { 
        state.counter += 10 
    }) 
};

四、actions

在 src/store/demo.ts 文件中的 actions 中定义 add 方法:

import { defineStore } from 'pinia'; 
export const demoStore = defineStore('demo', { 
    state: () => { 
        return { 
            // 所有这些属性都将自动推断其类型 
            counter: 0, 
        } 
    }, 
    getters:{}, 
    actions:{ 
        add(n){ 
            this.counter = n; 
        }, 
    } 
})

在页面中通过调用 store.add 方法来修改:

const add = () => store.add(10)

Getters的使用

getters 与 vue 中的 computed 类似,提供计算属性:

// store/demo.ts 
export const demoStore = defineStore('demo', {
    state: () => { 
        return { 
            mobile:"13111111111" 
        } }, 
        getters:{ 
            mobileHidden:(state) => { 
                return state.mobile.replace(/(\d{3})\d{4}(\d{4})/g,`$1****$2`); 
            } 
        }, 
        actions:{} 
 })

在页面中使用同 state

store互调

假设我们有多个 store,他们之间也是可以互相调用的,需要先将 testStore 调用实例化,然后读取里面方法:

// store/demo.ts 
import { defineStore } from 'pinia'; 
// 引入第二个store 
import { testStore } from './test'; 

export const demoStore = defineStore('demo', { 
    state: () => { 
        return {} 
    }, 
    getters:{}, 
    actions:{ 
        getList(){ 
            const store2 = testStore(); 
            console.log(store2.fn()) 
        } 
    } 
})