VueX是什么

38 阅读2分钟

VueX

Vuex 是 Vue.js 应用程序的状态管理模式。它集中存储应用的所有组件的状态,并提供了一种可预测的方式来修改和跟踪状态的变化。

对于组件间的通信方式而言,vuex也是一个可以进行任意组件通信的方法。 需要注意的是,在下面的示例代码中,所提到的辅助函数与直接从$Store中获取的方式不能再同一个文件中进行书写,要保持代码的统一性

核心概念:

State(状态):Vuex 使用单一状态树,即一个对象包含了全部的应用级别状态。可以通过 this.store.state来访问状态。Getters(获取器):类似于计算属性,用于对state中的数据进行一些处理后返回。Mutations(突变):用于修改state中的数据,需要是同步函数。Actions(动作):类似于Mutations,但可以包含异步操作。通过this.store.state 来访问状态。 Getters(获取器):类似于计算属性,用于对 state 中的数据进行一些处理后返回。 Mutations(突变):用于修改 state 中的数据,需要是同步函数。 Actions(动作):类似于 Mutations,但可以包含异步操作。通过 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的一些见解,感谢补充与指正。谢谢您的阅读,祝您生活愉快,工作顺利~