以下是“详解Vuex的属性和作用”的完整攻略。
什么是Vuex
Vuex是一个专门为Vue.js设计的状态管理库。Vuex集中式存储管理了整个应用的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex的核心概念
Vuex中包括了5个核心概念:
state
它表示保存整个应用状态的对象。初始状态可以在这里定义,并且它可以包含很多的属性。
getter
Vuex允许在store中定义“getter”(可以认为是store的计算属性)。Getter接受state作为其第一个参数,并且我们可以基于它来计算出一个新的状态。
mutation
改变state的唯一方法就是提交mutation。mutation就像事件,每个mutation都有一个字符串类型的事件类型和一个回调函数。这个回调函数就是我们实际进行状态更改的地方。
action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
module
用于将单一的store
拆分为多个模块。
Vuex的属性
在Vuex中我们可以通过一些属性来访问store中的状态:
Getters
我们可以通过 getters 进行一些复杂的计算,访问 state
中的值。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '任务1', done: true },
{ id: 2, text: '任务2', done: false },
{ id: 3, text: '任务3', done: true }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodoCount: (state, getters) => {
return getters.doneTodos.length
},
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
})
- 第一个getter函数
doneTodos
返回所有已完成任务的 todo。 - 第二个getter函数
doneTodoCount
返回已完成任务数量。 - 第三个getter函数
getTodoById
返回匹配todo的id
Mutations
我们使用mutation来变更状态,一般情况下,我们会通过一个类型和回调函数来注册一个mutation:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
当我们需要改变state里面的数据时,我们可以通过commit。举个例子:
store.commit('increment')
Actions
actions 和 mutations 类似,它们都是用来改变状态的,但是actions和mutations之间的区别是:
- 使用mutations更改state是同步的,而actions更改state是异步的。
- 提交mutations可以改变store中的状态,提交actions可以包含异步操作,提交mutations之前经常使用actions来处理数据。
actions是可以包含任意异步操作的,可以直接访问到全局的state,比如调用api接口:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
asyncIncrement ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
store.dispatch('asyncIncrement')
代码中定义了一个异步的action方法asyncIncrement。在异步操作成功后,通过commit调用同步的mutation来更新state里的数据。
Modules
当store对象变得非常大时,我们需要将其拆分为较小和更具体的模块 - 每个模块都有自己的 state、mutations、actions 和 getters 等。
const moduleA = {
state: {},
mutations: {},
actions: {},
getters: {}
}
const moduleB = {
state: {},
mutations: {},
actions: {},
getters: {}
}
const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
例子
以下是一个简单的示例,演示如何在Vuex中应用它的属性和方法。这个例子基于一个简单的todo列表。
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
todos: [
{ id: 1, text: '任务1', done: true },
{ id: 2, text: '任务2', done: false },
{ id: 3, text: '任务3', done: true }
]
}
const getters = {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodoCount: (state, getters) => {
return getters.doneTodos.length
}
}
const mutations = {
addTodo: (state, todo) => {
state.todos.push(todo)
},
toggleTodo: (state, todo) => {
todo.done = !todo.done
}
}
const actions = {
addTodo: ({ commit }, todo) => {
commit('addTodo', todo)
},
toggleTodo: ({ commit }, todo) => {
commit('toggleTodo', todo)
}
}
export default new Vuex.Store({
state,
getters,
mutations,
actions
})
然后,在我们的Vue组件中使用store:
<template>
<div>
<h1>Todo List</h1>
<ul>
<li v-for="todo in todos" :key="todo.id">
<input type="checkbox" :checked="todo.done" @click="toggleTodo(todo)">
{{ todo.text }}
</li>
</ul>
<form v-on:submit.prevent="addTodo">
<label for="task">添加任务</label>
<input type="text" id="task" v-model="newTodoText">
<button type="submit">添加</button>
</form>
<p>当前已完成任务 {{ doneTodoCount }}/{{ todos.length }}</p>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
data() {
return {
newTodoText: ''
}
},
computed: {
...mapGetters([
'doneTodos',
'doneTodoCount'
]),
todos() {
return this.$store.state.todos
}
},
methods: {
...mapActions([
'addTodo',
'toggleTodo'
]),
}
}
</script>
在此Vue组件中,我们使用了mapGetters
和mapActions
函数,来将store中的getters和actions映射到Vue组件中。此外,我们还从store里直接获取state中的todos数据。
另一个例子,假设在前面的例子中,我们需要根据数据从后台调用用户信息。代码如下:
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
todos: [
{ id: 1, text: '任务1', done: true, userId: 1 },
{ id: 2, text: '任务2', done: false, userId: 1 },
{ id: 3, text: '任务3', done: true, userId: 2 }
],
users: {
1: { id: 1, name: 'Lucy' },
2: { id: 2, name: 'Lily' }
}
}
const getters = {
todoList: state => {
return state.todos.map((todo) => {
todo.user = state.users[todo.userId]
return todo
})
}
}
const store = new Vuex.Store({
state,
getters
})
export default store
在这个例子中,我们有一个新的“users”状态,它包含一个id到user对象的映射。getters传递给我们的“todoList”映射包含了“user”对象。我们可以简单地在模板中访问这个属性。
<template>
<div>
<ul>
<li v-for="todo in todoList" :key="todo.id">
<input type="checkbox" :checked="todo.done" @change="toggleDone(todo)">
{{ todo.text }}
<span>{{ todo.user.name }}</span>
</li>
</ul>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default{
computed: {
...mapGetters([
'todoList'
])
},
methods: {
...mapActions([
'toggleDone'
]),
}
}
</script>
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Vuex的属性和作用 - Python技术站