导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

业务技能

针对性攻坚

AI


比较

优点

安装

npm install pinia

配置

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router/index'
import axios from 'axios'
import { createPinia } from 'pinia'

const app = createApp(App)
app.config.globalProperties.$axios = axios
app
  .use(router)
  .use(createPinia())
  .mount('#app')

定义

import { defineStore } from 'pinia'

interface IUser {
  name: string
  age: number
}
export const useUserStore = defineStore('user', {
  state(): IUser {
    return {
      name: '',
      age: 0,
    }
  },
  getters: {},
  actions: {
    updateUser(user: IUser) {
      this.name = user.name
      this.age = user.age
    },
  },
})

使用

state

基本使用

<template>
  <div>userAge: {{ user.age }}</div>
</template>
<script setup lang="ts">
import { useUserStore } from '../pinia/user'
const user = useUserStore()
setTimeout(() => {
  user.updateUser({
    name: 'Sherry',
    age: 30
  })
}, 500)
</script>

storeToRefs 使解构能响应式

<template>
  <div>userAge: {{ age }}</div>
</template>
<script setup lang="ts">
import { useUserStore } from '../pinia/user'
import { storeToRefs } from 'pinia'

const user = useUserStore()
// 使解构后的值也能拥有响应式
const { age } = storeToRefs(user)
setTimeout(() => {
  user.updateUser({
    name: 'Sherry',
    age: 30
  })
}, 500)
</script>

修改 state 的方式

<template>
  <div>Name: {{ name }}</div>
  <div>Age: {{ age }}</div>
</template>
<script setup lang="ts">
import { useUserStore } from '../pinia/user'
import { storeToRefs } from 'pinia'

const user = useUserStore()
// 使解构后的值也能拥有响应式
const { age, name } = storeToRefs(user)
setTimeout(() => {
  // 1. 直接修改(不建议)
  // user.age = 200
  // 2. $patch(传递对象,多个数据修改)(不建议)
  user.$patch({
    name: 'Lance',
    age: 28,
  })
  // 3. $patch(传递箭头函数,多个数据修改)(不建议)
  user.$patch((state) => {
    state.name = 'GC'
    state.age = 31
  })
  // 4. 直接调用 action (推荐)
  user.updateInfo({
    name: 'QB',
    age: 29,
  })
}, 500)
</script>

getters

无参数传递 vs 有参数传递

import { defineStore } from 'pinia'

interface IUser {
  name: string
  age: number
}
export const useUserStore = defineStore('user', {
  state(): IUser {
    return {
      name: '',
      age: 0,
    }
  },
  getters: {
    getAge(): number {
      return this.age
    },
    // 接受参数
    getFormatName(state): (value: string) => string {
      return (value: string) => {
        return state.name + value
      }
    },
  },
  actions: {
    updateInfo(user: IUser) {
      this.name = user.name
      this.age = user.age
    },
  },
})

<template>
  <div>Name: {{ name }}</div>
  <div>Age: {{ age }} - {{ getAge }} - {{ getFormatName('Lance') }}</div>
</template>
<script setup lang="ts">
import { useUserStore } from '../pinia/user'
import { storeToRefs } from 'pinia'
const user = useUserStore()
const { age, name, getAge, getFormatName } = storeToRefs(user)
setTimeout(() => {
  user.updateInfo({
    name: 'QB',
    age: 29,
  })
}, 500)
</script>

跨模块更新数据

定义两个模块

import { defineStore } from 'pinia'

export const useSubjectStore = defineStore('subject', {
  state() {
    return {
      courseList: ['数学', '语文'],
      currentIdx: 0,
    }
  },
})

然后我们希望在 user 模块中修改 subject 数据:

import { defineStore } from 'pinia'
import { useSubjectStore } from './subject'
const subject = useSubjectStore()
...
export const useUserStore = defineStore('user', {
  state(): IUser {
    return {
      ...
    }
  },
  getters: {
    ...
  },
  actions: {
    ...
    addCourse(course: string) {
      subject.courseList.push(course)
    },
  },
})

页面中使用

<template>
  ...
  <div>courseList: {{ subject.courseList.join(',') }}</div>
</template>
<script setup lang="ts">
import { useUserStore } from '../pinia/user'
import { useSubjectStore } from '../pinia/subject'

const user = useUserStore()
const subject = useSubjectStore()
user.addCourse('英语')
</script>