Vuex 的使用方式及其特点
Vuex是Vue.js框架中用于管理应用程序状态的官方插件。它的使用方式如下:
- 定义状态:在Vuex中,状态被定义为一个包含数据的对象,通过State属性来存储。例如:
const store = new Vuex.Store({
state: {
count: 0
}
})
- 修改状态:Vuex要求所有状态的修改都必须通过mutations来进行,以保证状态变更的可追踪和可调试性。例如:
store.commit('increment')
- 访问状态:可以通过getters来访问store中的状态,并进行一些计算操作。例如:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
- 异步操作:Vuex允许在actions中进行异步操作,例如发起Ajax请求等。例如:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
Vuex的特点如下:
-
集中化状态管理:Vuex将应用程序的状态集中存储在一个单一的store中,这使得状态管理变得更加简单和可维护。
-
可追踪性:所有对状态的修改都必须通过mutations来进行,这使得状态的变化可以被跟踪并且容易调试。
-
组件通信:Vuex允许组件之间进行状态共享,从而避免了父子组件传递数据时可能出现的繁琐问题。
-
插件扩展:Vuex提供了一些插件扩展机制,可以方便地扩展其功能,例如开发调试工具等。
理解 store、state、getter、mutation 和 action 的概念
-
Store: Pinia 的核心是 store,它是一个容器,可以存储应用程序的所有状态。我们可以创建多个 store,每个 store 都有自己的 state、getter、mutation 和 action。
-
State: 每个 store 都有一个 state 对象,它包含了该 store 的所有状态。我们通过修改 state 对象来改变应用程序的状态。
-
Getter: Getter 可以从 state 中派生出新的状态,并将其暴露给组件。Getter 可以接受其他 getter 作为参数,这使得我们可以把 getter 组合在一起来获得更复杂的派生状态。
-
Mutation: Mutation 用于修改 state。Mutation 接受 state 作为第一个参数,以及一个 payload 作为第二个参数。Mutation 应该是同步的,因为它们必须是可追踪的,并且可以记录到日志中。
-
Action: Action 用于处理异步操作,例如 API 请求或定时器等。Action 可以触发 Mutation,并且可以返回 Promise 或其他值。与 Mutation 不同,Action 不会直接修改 state。
Vuex 和 Pinia 的异同
Vuex 和 Pinia 都是用于状态管理的库,主要用于 Vue.js 应用程序中。它们都提供了一种在组件之间共享状态的机制,以简化应用程序的复杂性并提高开发效率。
然而,在设计和实现上,Vuex 和 Pinia 有一些重要的异同:
-
设计理念不同:Vuex 的设计灵感来自 Flux 和 Redux,其核心思想是将应用程序状态存储在单个中央存储库中,并使用 mutation 修改该状态。而 Pinia 更加轻量级,采用了基于函数的 API 管理状态,并将状态分散到多个 store 中。
-
代码量不同:相对于 Vuex 而言,Pinia 所需的代码量较少,代码结构也更加清晰简洁。这归功于 Pinia 的基于函数的 API 和 TypeScript 支持。
-
性能表现不同:在性能方面,Pinia 常常表现出比 Vuex 更好的性能。这是因为 Pinia 没有使用 Vuex 的严格响应式系统,而是使用了更轻量级的 Vue 3 组件 API。
-
对 TypeScript 的支持不同:Pinia 受益于 Vue 3 的完全 TypeScript 支持,其 API 具有良好的类型推断功能。Vuex 也提供了 TypeScript 类型定义文件,但需要手动安装。
总体而言,Pinia 适合于那些想要更轻量级状态管理方案的开发者,而 Vuex 则是更适合需要更严格的状态管理和更大型应用程序的开发者。
如何创建一个 Pinia store
要创建一个 Pinia store,可以按照以下步骤进行操作:
-
安装 Pinia 库和 Vue.js:在项目中使用 npm 或 yarn 安装 Pinia 和 Vue.js。
npm install pinia vue
-
创建一个 Pinia 实例:在 main.js 文件中创建一个 Pinia 实例,并把它挂载到 Vue 实例上。
import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) const pinia = createPinia() app.use(pinia) app.mount('#app')
-
创建一个 store:使用
defineStore
函数创建一个 store,并定义它的状态、操作和 getter 方法。import { defineStore } from 'pinia' export const useCounterStore = defineStore({ id: 'counter', state: () => ({ count: 0, }), actions: { increment() { this.count++ }, }, getters: { doubleCount() { return this.count * 2 }, }, })
-
在组件中使用 store
<template> <div> <p>Count: {{ count }}</p> <p>Double Count: {{ doubleCount }}</p> <button @click="increment">Increment</button> </div> </template> <script> import { useCounterStore } from './counterStore' export default { setup() { const counterStore = useCounterStore() return { count: counterStore.count, doubleCount: counterStore.doubleCount, increment: counterStore.increment, } }, } </script>
这样,就可以创建并使用一个简单的 Pinia store 了。
修改state的方式
1、可通过sotre直接修改
import { useStore } from '@/stores/useState'
const personStore = useStore()
personStore.name = 'test'
2、可以通过storeToRefs转为ref
import { storeToRefs } from 'pinia'
import { useStore } from '@/stores/useState'
const personStore = useStore()
const { age, name } = storeToRefs(personStore);
name.value = 'test'
3、可通过$patch传对象参数修改, 可同时修改多个数据
import { useStore } from '@/stores/useState'
const personStore = useStore()
personStore.$patch({
name: 'test',
age:18
})
4、可通过$patch传函数参数修改
import { useStore } from '@/stores/useState'
const personStore = useStore()
personStore.$patch( state => {
state.name = 'test'
state.children.push({ name: 'test1' })
})
5、通过$state 属性设置为新对象来替换 Store 的整个状态
import { useStore } from '@/stores/useState'
const personStore = useStore()
personStore.$state = {
name: '小黑',
age: 20
}
如何在组件中获取和更新 Pinia store 中的状态
- 创建一个 Pinia store:在你的应用程序中创建一个 Pinia store,可以使用
defineStore
函数来创建。例如,在store.js
文件中创建一个名为counter
的 store:
import { defineStore } from "pinia";
export const useCounterStore = defineStore({
id: "counter",
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++;
},
decrement() {
this.count--;
},
},
});
- 在组件中引入 store:在需要访问 store 的组件中,在
Counter.vue
组件中引入counter
store:
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script>
import { useCounterStore } from "@/store";
export default {
setup() {
const counterStore = useCounterStore();
return {
count: counterStore.count,
increment: counterStore.increment,
decrement: counterStore.decrement,
};
},
};
</script>
-
使用 store 中的状态和方法:在组件中,可以通过 store 实例直接访问 store 中的状态和方法。在上面的例子中,我们在
setup()
函数中创建了一个counterStore
实例,然后将count
状态和increment()
和decrement()
方法传递给组件模板。 -
更新 store 中的状态:要更新 store 中的状态,可以直接调用 store 中的方法。例如,在上面的例子中,我们可以通过在模板中点击 “+” 或 “-” 按钮来调用
increment()
和decrement()
方法来更新count
状态。