VueX
Vuex 是 Vue.js 应用程序的状态管理模式。它集中存储应用的所有组件的状态,并提供了一种可预测的方式来修改和跟踪状态的变化。
对于组件间的通信方式而言,vuex也是一个可以进行任意组件通信的方法。 需要注意的是,在下面的示例代码中,所提到的辅助函数与直接从$Store中获取的方式不能再同一个文件中进行书写,要保持代码的统一性
核心概念:
State(状态):Vuex 使用单一状态树,即一个对象包含了全部的应用级别状态。可以通过 this.store.dispatch('actionName') 触发。 Modules(模块):将 store 分割成模块,每个模块拥有自己的 state、getters、mutations 和 actions。
state
state是状态数据,可以通过this.$store.state来直接获取状态,也可以利用vuex提供的mapState辅助函数将state映射到计算属性(computed)中去。 以下就是state的两种使用方式: 不过需要注意的是如果使用vuex提供的mapState辅助函数时需要先从vuex中引入mapState
<script>
// 我们需要在store文件中定义
export default {
state: {
name: 'Jay',
age: 18
}
}
</script>
<!-- 然后在需要使用的组件中 -->
<script>
<template>
<span>姓名:{{ name }};年龄:{{ age }}</span>
<span>姓名:{{ myName }};年龄:{{ myAge }}</span>
<span>姓名:{{ $store.state.name }};年龄:{{ $store.state.age }}</span>
</template>
import {mapState} from 'vuex';
export default {
computed: {
...mapState(['name', 'age'])
},
data() {
return {
myName: '',
myAge: ''
}
},
mounted() {
const {name, age} = this.$store.state
this.myName = name
this.myAge = age
}
}
</script>
getters
在 Vuex 中,getters 允许你在访问 store 中的状态时进行一些计算或转换。getters 可以被认为是 store 的计算属性,类似于 Vue 组件中的计算属性,但是可以被多个组件共享和重用。 主要作用和理解:
- 计算属性:getters 可以用来对 store 中的状态进行计算,根据需要派生出一些新的状态,而不改变 store 中的原始状态。
- 数据筛选和转换:你可以使用 getters 对 store 中的数据进行筛选、排序、过滤或转换,以便在组件中更方便地使用。
- 重用逻辑:将一些常用的逻辑抽取到 getters 中,可以在多个组件中重用这些逻辑,避免代码重复。 使用方式:
<script>
export default {
state: {
todoList: [{id: 1, text: '吃饭', done: true},{id: 2, text: '睡觉', done: false}]
},
getters: {
doneTodo: state => state.todoList.filter(todo => todo.done),
doneTodoCount: (state, getters) => getters.doneTodo.length
}
}
</script>
<!-- 我们在组件中去进行使用的时候 -->
<template>
<span>完成的todo: {{ doneTodo }}; 数目为:{{ doneTodoCount }}</span>
<span>完成的todo: {{ todos }}; 数目为:{{ count }}</span>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
data() {
return {
todos: [],
count: null
}
},
mounted() {
const {doneTodo,doneTodoCount} = this.$store.getters
this.todos = doneTodo
this.count = doneTodoCount
},
computed: {
...mapGetters(['doneTodo','doneTodoCount'])
}
}
</script>
mutations
更改 Vuex 的 store 中的修改状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。
<script>
export default {
state: {
count: 1
},
mutations: {
ADD: (state) => {
state.count ++
},
reset: (state, value) => {
state.count = value
}
}
}
</script>
<!-- 组件中使用 -->
<template>
<div>
<span>{{ $store.state.count }}</span>
<button @click="handleAdd">点击数目 + 1</button>
<button @click="reset">重置数目</button>
</div>
</template>
<script>
import {mapMutations} from 'vuex'
export default {
methods: {
...mapMutations(['add','reset']),
handleAdd() {
this.$store.commit('add')
},
reset() {
this.$store.commit('reset')
}
}
}
</script>
actions
actions和mutations相似,但mutations一般是进行同步的操作,若要进行异步操作,使用actions actions中:
- 可以包含异步操作:actions 用于处理异步操作、封装复杂的业务逻辑或者多个 mutation 的调用。可以在 actions 中执行异步操作,如请求后端数据、定时器等。
- 触发mutations:actions 通过 commit 方法来触发 mutations,从而间接改变 store 中的状态。
- 组合多个mutations:actions 可以组合多个 mutations 的操作,可以实现一系列的状态变更。
- 对mutations进行封装:actions 可以对多个 mutations 进行封装,使得代码更加模块化和可维护。
<script>
export default {
state: {
count: 1
},
mutations: {
ADD: (state) => {
state.count ++
},
reset: (state, value) => {
state.count = value
}
},
actions: {
asyncAdd({commit}) {
setTimeout(() => {
commit('add')
}, 3000);
}
}
}
</script>
<!-- 组件中使用 -->
<template>
<div>
<span>{{ $store.state.count }}</span>
<button @click="handleAdd">点击3秒后数目 + 1</button>
<button @click="reset">重置数目</button>
</div>
</template>
<script>
import {mapMutations,mapActions} from 'vuex'
export default {
methods: {
...mapMutations(['add','reset']),
...mapActions(['asyncAdd']),
handleAdd() {
this.$store.dispatch('asyncAdd')
},
reset() {
this.$store.commit('reset')
}
}
}
</script>
modules
当遇见大型项目时,数据量大,store就会显得很臃肿,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割在模块中使用:namespaced: true, 命名空间,添加之后,当前模块下的标识符可以和其它模块相同,用于解决不同模块的命名冲突问题。
import { createStore } from 'vuex';
const files = require.context('./modules', false, /\.js$/);
const modules = {}
files.keys().forEach((key) => {
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
})
export default createStore({
modules
});
// 使用这个方式可以直接将modules文件夹下面的自动添加到store下,且模块的名字为文件的名字
以上就是对于VueX的一些见解,感谢补充与指正。谢谢您的阅读,祝您生活愉快,工作顺利~