一、安装Pinia

npm install pinia
  • 1.

二、在src/main.ts中引入并使用Pinia

// 引入 createApp 用于创建应用
import { createApp } from "vue";
// 引入 App 根组件
import App from './App.vue'
// 引入路由器
import router from "./router";
// 1、引入 createPinia
import { createPinia } from "pinia";


// 创建一个应用
const app = createApp(App)
// 使用路由器
app.use(router)

// 2、创建Pinia
const pinia = createPinia()
// 3、使用Pinia
app.use(pinia)

// 挂载整个应用到 app 容器中
// .mount() 方法应该始终在整个应用配置和资源注册完成后被调用。同时请注意,不同于其他资源注册方法,它的返回值是根组件实例而非应用实例。
app.mount('#app')
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

只要使用了Pinia,即app.use(pinia),则在vue.js devtools中立马能看到Pinia。如下图(Edge浏览器)。

Vue3 整合 Pinia 存储数据_vue

三、代码案例

1、新建文件src/store/loveTalk.ts。(文件名你随意,只要在store目录下就行)
import axios from "axios";
import { defineStore } from "pinia";
import { reactive } from "vue";

const useLoveTalkStore = defineStore('love-talk-id', () => {
    // 相当于[state-状态]    先从浏览器的 localStorage 中取值
    const loveTalks: string[] = reactive(JSON.parse(localStorage.getItem('loveTalks') as string) || [])

    // 相当于[actions-动作]
    async function addLoveTalk() {
        const { data: { code, content } } = await axios.get('https://api.uomg.com/api/rand.qinghua');
        console.log('情话:', code, content);
        if (code === 1) {
            // loveTalks 数组头部插入
            loveTalks.unshift(content)
            // 存储到浏览器的 localStorage 中,实现页面刷新数据不丢失
            storeToLocalStorage()
        }
    }

    // 存储数据到客户端,实现页面刷新数据不丢失
    function storeToLocalStorage() {
        localStorage.setItem('loveTalks', JSON.stringify(loveTalks))
    }

    // 向外暴露
    return { loveTalks, addLoveTalk }
})

// 暴露useLoveTalkStore
export default useLoveTalkStore
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
2、App.vue(App.vue是作者用来展示效果的页面,你们若不嫌麻烦,可以使用其他页面)
<template>
  <div class="app">
    <h2>父组件</h2>
    <p>
      宣言:
    <ul>
      <li v-for="(loveTalk, index) in loveTalks" :key="index">{{ loveTalk }}</li>
    </ul>
    </p>
    <button @click="addLoveTalk">甜蜜暴坤</button>
    <hr />
  </div>
</template>


<script setup lang="ts" name="App">
  import useLoveTalkStore from './store/loveTalk';
  import { storeToRefs } from 'pinia';
  import { toRefs } from 'vue';

  let loveTalkStore = useLoveTalkStore()
  // 可以直接从 useLoveTalkStore() 结果中解构方法
  const { addLoveTalk } = loveTalkStore
  console.log('loveTalkStore === ', loveTalkStore);

  // 解构时,需要对数据做 storeToRefs 或 toRefs 操作,以保证 state 数据的响应式
  // storeToRefs 只对 loveTalkStore 中的 state 做 toRefs 操作
  const { loveTalks } = storeToRefs(loveTalkStore)
  console.log('storeToRefs(loveTalkStore) === ', loveTalks);

  // toRefs 会对 loveTalkStore 中的所有属性做 toRefs 操作
  console.log('toRefs(loveTalkStore) === ', toRefs(loveTalkStore));
  
</script>


<style lang="scss" scoped>
  .app {
    margin: 150px;
    padding: 30px;
    background-color: bisque;
  }
</style>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
3、效果如下,刷新页面数据不会丢失。因为数据存储到浏览器的localStorage中了,每次刷新时Pinia都会先从localStorage中读取数据赋给loveTalks

Vue3 整合 Pinia 存储数据_Pinia_02

四、修改 Pinia 中的 state 数据

1、直接获取state并修改
let loveTalkStore = useLoveTalkStore()
loveTalkStore.loveTalks.shift()

// 注意:只是修改了Pinia中的loveTalks的值,页面刷新数据也会重置。
// 想要保证页面刷新不丢失,可借助客户端存储 localStorage.setItem('xxx', xxx)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
2、$patch批量修改
loveTalkStore.$patch((state) => {
	state.a = 100
	state.b = 200,
	// 清空数组。注意:要调用数组提供的api才能保留响应式
	state.loveTalks.splice(0, state.loveTalks.length)
})

// 注意:只是修改了Pinia中的loveTalks的值,页面刷新数据也会重置。
// 想要保证页面刷新不丢失,可借助客户端存储 localStorage.setItem('xxx', xxx)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
3、调用store中的actions
1)调用页面:
	addLoveTalk()2)自定义的store.ts:

  // 相当于[state-状态]    先从浏览器的 localStorage 中取值
  let loveTalks: string[] = reactive(JSON.parse(localStorage.getItem('loveTalks') as string) || [])


  // 相当于[actions-动作]
  function addLoveTalk() {
    // loveTalks 数组头部插入
    // loveTalks.unshift(content)
    // 清空数组
    loveTalks.splice(0, loveTalks.length)
    // 存储到浏览器的 localStorage 中,实现页面刷新数据不丢失
    storeToLocalStorage()
  }

  // 存储数据到客户端,实现页面刷新数据不丢失
  function storeToLocalStorage() {
    localStorage.setItem('loveTalks', JSON.stringify(loveTalks))
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.