自学内容网 自学内容网

Pinia

Vuex4 匹配 Vue3;Vuex3 匹配 Vue2。
Vuex3 推荐搭配 Vue2 使用;Vuex4 推荐搭配 Vue2 和 Vue3 的 Options API 使用;Pinia 推荐搭配 Vue3 的 Composition API 使用。

Pinia: 也是 Vue 官方维护的一个状态管理库,用于跨组件、页面进行状态共享。

Pinia 和 Vuex 的区别:

Pinia 原本是 Vue 官方对 Vuex5 的一个实验性版本,不过完善之后官方就将其直接推出了,而不再去发布 Vuex5。

  1. 在 Pinia 中,mutations 不再存在。
  2. 在 Pinia 中,不再有 modules 的模块嵌套。
    在这里插入图片描述
  3. 相比于 Vuex,Pinia 对 Composition API 有更友好的适配。
  4. 相比于 Vuex,Pinia 对 TypeScript 有更友好的支持。

安装:

npm install pinia

创建并注册 Pinia 对象:

// src/stores/index.js
// 1. 创建 Pinia 对象
import { createPinia } from "pinia"
const pinia = createPinia()
console.log(pinia.state)
export default pinia
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import pinia from './store'

const app = createApp(App)
// 2. 注册 pinia 对象,此时 Piani 就生效了
app.use(pinia)
app.mount('#app')

定义并获取 Store:

通过 defineStore() 定义 store。defineStore() 接收两个参数,第一个参数是当前 store 的唯一标识 id;第二个参数是当前 store 的配置对象。defineStore() 返回一个函数,调用返回的函数就会创建并返回 store。

import { defineStore } from "pinia"

// 1. 定义 store。通过 defineStore() 定义 store。在 Pinia 中可以定义任意数量的 store。定义好 store 之后,不需要手动将其加入到 pinia 中,pinia 会自动对其进行管理
const useHome = defineStore('home', {...})

// 2. 获取 store。通过调用 defineStore() 返回的函数创建 store
const homeStore = useHome()

使用:

Store 有三个核心概念:state、getters、actions,等同于 Vue 组件中的 data、computed、methods。一旦 store 被实例化,就可以直接在 store 上访问 state、getters、actions 中定义的任何属性和方法。

state:

state:相当于组件中的 data。用来管理状态。

// src/store/home.js
import { defineStore } from "pinia"

const useHome = defineStore('home', {
    // 1. 定义 state 状态
    state: () => ({
        count: 1,
    })
})

export default useHome
// src/components/Home.vue
<template>
  <div>{{ homeStore.count }}</div>
</template>

<script setup>
// 2. 获取 state 状态。
import useHome  from './store/home'
const homeStore = useHome()
console.log(homeStore.count)
</script>

<style scoped>
</style>  

对 store 中的数据进行赋值或者解构,赋值或者解构出来的数据不具有响应式。可以使用 Vue 提供的 toRefs() 方法或者 Pinia 提供的 storeToRefs() 方法使其具有响应式。

// src/components/Home.vue
<template>
  <div>{{ count }}</div>
  <button @click="hadnleAdd">+1</button>
</template>

<script setup>
import useHome  from './store/home'

const homeStore = useHome()
// 赋值或者解构出来的数据不具有响应式
let {count} = homeStore
const hadnleAdd = () => {
  count++
}
</script>

<style scoped>
</style> 
<template>
  <div>{{ count }}</div>
  <button @click="hadnleAdd">+1</button>
</template>

<script setup>
// import { toRefs } from 'vue'
import { storeToRefs } from 'pinia'
import useHome  from './store/home'

const homeStore = useHome()
// 通过使用 toRefs() 或者 storeToRefs() 使得赋值或者解构出来的数据仍然具有响应性
// let {count} = toRefs(homeStore)
let {count} = storeToRefs(homeStore)
const hadnleAdd = () => {
  homeStore.count++ // 但此处修改数据还需要使用 homeStore.count++,不能直接使用 count++
}
</script>

<style scoped>
</style>  
修改 state:

在 Pinia 中,可以直接修改 state,而不需要像在 Vuex 中一样必须通过提交 mutation 来修改 state。

可以通过 store 实例直接修改 state。

<template>
  <div>{{ homeStore.count }}</div>
  <button @click="hadnleAdd">+1</button>
</template>

<script setup>
import useHome  from './store/home'

const homeStore = useHome()
const hadnleAdd = () => {
  // 通过 store 实例直接修改 state
  homeStore.count++
}
</script>

<style scoped>
</style>  

也可以通过 store 实例的 $patch() 方法一次性修改多个状态。

homeStore.$patch({
    name: 'Lee',
    age: 18,
    height: 1.88,
  })

也可以通过调用 store 实例的 $reset() 方法将状态重置回初始值。

homeStore.$reset()

getters:

getters:相当于组件中的 computed。如果需要对数据进行处理后再使用,就可以使用 getters。

// src/store/home.js
import { defineStore } from "pinia"

const useHome = defineStore('home', {
    state: () => ({
        count: 1,
    }),
    // 1. 定义 getters
    getters: {
        doubleCount(state) {
            // 默认会接收 state 作为参数,因此可以使用 state 访问 state 中的数据
            return state.count * 2
            // 在 getters 中可以使用 this,this 指向 store 实例,因此也可以使用 this 访问 state 中的数据
            return this.count * 2
        }
    }
})

export default useHome
// src/components/Home.vue
<template>
  <div>{{ homeStore.doubleCount }}</div>
</template>

<script setup>
// 2. 获取 getters 中的数据
import useHome  from './store/home'
const homeStore = useHome()
console.log(homeStore.doubleCount)
</script>

<style scoped>
</style>  

actions:

actions:相当于组件中的 methods。用来定义业务逻辑,经常会将组件中的网络请求抽取到 actions 中。

// src/store/home.js
import { defineStore } from "pinia"

const useHome = defineStore('home', {
    state: () => ({
        count: 1,
    }),
    // 1. 定义 actions
    actions: {
        // 可以接收调用时传递过来的参数
        increment() {
            // 在 actions 中可以使用 this,this 指向 store 实例
            this.count++ 
        }
    }
})

export default useHome
// src/components/Home.vue
<template>
  <div>{{ homeStore.count }}</div>
  <button @click="handleAdd">+1</button>
</template>

<script setup>
// 2. 使用 actions
import useHome  from './store/home'
const homeStore = useHome()
const handleAdd = () => {
  homeStore.increment()
}
</script>

<style scoped>
</style>  

原文地址:https://blog.csdn.net/wsln_123456/article/details/145135766

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!