惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
G
Google Developers Blog
P
Proofpoint News Feed
Recent Announcements
Recent Announcements
MyScale Blog
MyScale Blog
D
DataBreaches.Net
Stack Overflow Blog
Stack Overflow Blog
月光博客
月光博客
爱范儿
爱范儿
罗磊的独立博客
腾讯CDC
Hugging Face - Blog
Hugging Face - Blog
博客园 - 叶小钗
Vercel News
Vercel News
酷 壳 – CoolShell
酷 壳 – CoolShell
B
Blog
C
Check Point Blog
美团技术团队
宝玉的分享
宝玉的分享
Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

Mengke's blog - Mengke's coding journey

年轻不是健康的免死金牌 深圳工作机会,前端 2025 年终总结 Skill 不是 MCP 的替代品:我理解的渐进式披露与选型原则 独立开发者如何开具发票 香港银行卡开户完整指南(2025年9月最新) 招商银行储蓄卡微信动账提醒恢复方法 再谈 MCP - Model Context Protocol(MCP)详解和开发教程 Get Human-Readable "Time Ago" in TypeScript 以「asset-price-mcp」为例,从 0 开发 MCP Server Model Context Protocol (MCP) 快速开始 DeepSeek + Dify 搭建本地知识库 An elegant solution for implementing optional property types using TypeScript 2024 年终总结 Quickly Create a Fullscreen WebView with Autoplay Support for Testing 以数字开头的 ID 在 querySelector 中的处理 String casing utilities in JavaScript Check if a string is a valid color Simple Event-Emitter/PubSub pattern Find which process is running on a certain port and kill it Markdown Code block's basic and advanced syntaxes Common npm commands to use locally Pnpm aliases How to safely rename a case sensitive file/directory in a git repo? A custom hooks to use an async effect A custom hooks to use local storage state 🤩 Mengke'blog 上线的这一年 🗼 五月底去了一趟日本,记录一下我的游记和攻略 网站性能优化:如何高效预加载大型静态资源 闰年之约 - 2024年2月29日
Pinia 快速上手指南
Mengke · 2023-04-12 · via Mengke's blog - Mengke's coding journey

Server.webp

Published on
/

6 mins read

/

––– views

Share:

优势

  • vue 2、3 都支持。
  • 抛弃传统的 Mutation ,只有 stategetteraction ,简化了代码结构。
  • 不需要嵌套模块,符合 Composition API 代码风格。
  • 支持 TS。
  • 代码简洁。

安装

初始化项目: npm init vite@latest

安装 Pinia : npm i pinia

创建 Store

// src/store/index.ts
 
import { createPinia } from 'pinia'
 
const store = createPinia()
export default store

在 main.ts 中引入并使用:

// src/main.ts
 
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
 
const app = createApp(App)
app.use(store)

State

定义 state:

import { defineStore } from 'pinia'
 
export const useMainStore = defineStore('mainStore', {
  state: () => ({
    msg: 'Hello World!',
  }),
  getters: {},
  actions: {},
})

获取 state:

<template>
  <div>{{ store.msg }}</div>
</template>
<script lang="ts" setup>
  import { useMainStore } from '../../store'
  const store = useMainStore()
</script>

也可以结合 computed

const msg = computed(() => store.msg)

解构 state

需要同时获取 Store 中的多个值时,通常会使用解构赋值的方式。但在 Pinia 中直接解构会造成数据失去响应性:

<template>
    <div>{{ msg }}--{{ store.msg }}</div>
</template>
<script lang="ts" setup>
	import { useMainStore } from '../../store';
	const store = useMainStore();
	const { msg } = store;
	setTimeout(() => {
	    console.log("patch");
	    store.$patch({ msg: 'change' });
	}, 2000);
</script

Untitled

storeToRefs 结构方法:

import { storeToRefs } from 'pinia'
const { msg } = storeToRefs(store)

Untitled

修改 state

直接通过 store.属性名 来修改。

store.count = 100

多条数据修改:

  • 「不建议」多条数据的修改也可以直接通过 store.属性名 来修改:

    const change = () => {
      store.obj = { a: 8, b: 7, c: 9 }
    }
  • 使用 $patch来修改数据:

    // $patch 对象
    store.$patch({
      count: store.count + 2,
      msg: 'This is Pinia World',
    })
     
    // or
     
    // $patch 函数
    store.$patch((state) => {
      state.arrs.push({ name: 'haha', age: 12 })
      state.hasChange = true
    })
  • 通过 action 修改:

    export const useMainStore = defineStore('mainStore', {
      state: () => ({
        msg: 'Hello World!',
      }),
      getters: {},
      actions: {
        changeMsg(newMsg) {
          this.msg = newMsg
        },
      },
    })
     
    const store = useMainStore()
    store.changeMsg('哈哈哈')

Getters

等同于 store 的 state 的 计算值 。可以这样定义:

export const useMainStore = defineStore("mainStore", {
    state: () => ({
        msg: "Hello World!",
				users: [
            { id: 1, name: "aa" },
            { id: 2, name: "bb" },
            { id: 3, name: "cc" }
        ]
    }),
    getters: {
        myMsg(state) {
            return `${state.msg} === 111`;
        },
				// 访问其他 getter
        myMsg2(state): string {
            return `${this.getMsg} === 222`;
        },
				// 向 getter 传递参数
				getUserById: (state) => {
		      return (userId) => state.users.find((user) => user.id === userId)
		    },
    }
});
 
const store = useMainStore();
console.log(store.myMsg1);    // Hello World! === 111
console.log(store.myMsg2);    // Hello World! === 111 === 222
console.log(store.getUserById(2));    // { id: 2, name: "bb" }

getter 中传递参数的方法会让 getter 不再被缓存 ,不过我们可以手动做一下缓存:

export const useStore = defineStore('main', {
  getters: {
    getActiveUserById(state) {
      const activeUsers = state.users.filter((user) => user.active)
      return (userId) => activeUsers.find((user) => user.id === userId)
    },
  },
})

访问其他 store

export const useStore1 = defineStore('store1', () => {
  const store1Count = ref(2)
  return { store1Count }
})
export const useStore2 = defineStore('store2', {
  state: () => ({
    store2Count: 100,
  }),
  getters: {
    countTotal(state) {
      return useStore1().store1Count + state.store2Count
    },
  },
})
 
const store2 = useStore2()
console.log(store.countTotal) // 102

Actions

异步 action

export const useStore = defineStore('store', {
  actions: {
    async getData() {
      const response = await fetch('https://getman.cn/echo')
      const data = await response.text()
      return data
    },
  },
})
const store = useStore()
const data = await store.getData()
console.log(data)

action 相互调用

export const useUserStore = defineStore('store', {
  actions: {
    async login(account, pwd) {
      const { data } = await api.login(account, pwd)
      this.setData(data) // 调用另一个 action 的方法
      return data
    },
    setData(data) {
      console.log(data)
    },
  },
})

action 调用其他 store 的 action

同 getter;访问其他 store

数据持久化

插件 pinia-plugin-persist 可以辅助实现数据持久化功能。

安装

npm i pinia-plugin-persist --save

使用

// src/store/index.ts
 
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
 
const store = createPinia()
store.use(piniaPluginPersist)
 
export default store

接着在对应的 store 里开启 persist 即可。

export const useUserStore = defineStore('user', {
  state: () => ({
    name: '张三',
  }),
  // 开启数据缓存
  persist: {
    enabled: true,
  },
})

https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1dc6800f21674e3cbcc1fc02af4c7051~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp?

数据默认存在 sessionStorage 里,并且会以 store 的 id 作为 key。

自定义 key

你也可以在 strategies 里自定义 key 值,并将存放位置由 sessionStorage 改为 localStorage

persist: {
		enabled: true,
	  strategies: [
		    {
			      key: 'my_user',
			      storage: localStorage,
		    }
	  ]
}

https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/42ebf8aa98394052ad8fd5e4afb3ca3f~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp?

持久化部分 state

默认所有 state 都会进行缓存,你可以通过 paths 指定要持久化的字段,其他的则不会进行持久化。

state: () => ({
		name: "张三",
    age: 18,
    gender: "男"
}),
persist: {
    enabled: true,
    strategies: [
        {
            storage: localStorage,
            paths: ["name", "age"]
        }
    ]
}

上面我们只持久化 nameage,并将其改为 localStorage, 而 gender 不会被持久化,如果其状态发生更改,页面刷新时将会丢失,重新回到初始状态,而 nameage 则不会。


附:Pinia 速查表

1. 安装 Pinia

Untitled

2. 定义 store

Untitled

3. 使用 store (组合式 API)

Untitled

4. 使用 store (选项式 API)

Untitled

5. 修改 state

Untitled

6. 订阅修改

Untitled

Back to posts

On this page
  • 优势
  • 安装
  • 创建 Store
  • State
  • 定义 state:
  • 获取 state:
  • 解构 state
  • 修改 state
  • 多条数据修改:
  • Getters
  • 访问其他 store
  • Actions
  • 异步 action
  • action 相互调用
  • action 调用其他 store 的 action
  • 数据持久化
  • 安装
  • 使用
  • 自定义 key
  • 持久化部分 state
  • 附:Pinia 速查表
  • 1. 安装 Pinia
  • 2. 定义 store
  • 3. 使用 store (组合式 API)
  • 4. 使用 store (选项式 API)
  • 5. 修改 state
  • 6. 订阅修改