> 文章列表 > vuex数据管理详细总结以及项目示例

vuex数据管理详细总结以及项目示例

vuex数据管理详细总结以及项目示例

哈喽 大家好啊 最近遇到一个问题,关于多个子表单进行多选,然后请求发给后端,然后请教了下同事方案,可以用vuex,由于自己vuex用得少,也不是很熟,今天就从头学习下(申明:以下都是通过vuex官网学习总结的,所以很多都有相同的,只供学习,不用做商业用途。)

1.首先官网:Vuex 是什么? | Vuex (vuejs.org)

1.vuex是一个大型仓库

2.Vuex得状态存储是响应式得。当vuex组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会发生更新

3.不能直接更改store中的状态,改变store中的状态就是commit(提交) mutation

import {createApp} from 'vue'
import { createStore}  from 'vuex'// 创建一个新的store实例
const store = createStore({state()  {return {count: 0}},mutations: {increment(state) {state.count++}}})const app = createApp({/*根组件*/})
app.use(store)

然后通过store.state来获取状态对象,通过store.commit方法触发状态变更

store.commit('increment')
console.log(store.state.count)

在vuex组件中,可以通过this.$store访问store实例

在组件component.vue中

methods: {increment() {this.$store.commit('increment');console.log(this.$store.state.count)}
}

因为store中的状态是响应式的,所以调用store的状态只需要在计算属性中返回就可以了

触发变化也只需要在methods中提交mutation

1.State

import {mapState}  form 'vuex';export default {computed: mapState({// 箭头函数可以使代码更简洁const: state => state.count,// 传字符参数'count',等同于state=> state.countcountAlias: 'count',为了能够使用this获取局部状态,必须使用常规函数countPlusLocalState(state) {return state.count + this.localCount}})
}

对象展开运算符

mapState 函数返回的是一个对象。我们如何将它与局部计算属性混合使用呢?通常,我们需要使用一个工具函数将多个对象合并为一个,以使我们可以将最终对象传给 computed 属性。但是自从有了对象展开运算符,我们可以极大地简化写法:

computed: {localComputed() {....}// 使用对象展开运算符将此对象混入到外部对象中...mapState({})
}

Getter:

const store = createStore ({state: {todos: [{id: 1,text: '...',done: true},{id: 2,text: '...',done: false}]    },// getters是对state里面的数据进行直接计算能得到的getters: {doneTodos(state) {return state.todos.fillter(todo => todo.done)},doneTodosCount(state,getters) {return getters.doneTodos.length},// 可以通过getter返回一个函数,来实现给getter传参,在你对store里面的数组进行查询getTodoById:(state) => (id) => {return state.todos.find(todo => todo.id === id)}}
})我们在其他组件中使用:
computed: {doneTodosCount() {return this.$store.getters.doneTodosCount}
// 注意: getter在通过属性访问时是作为Vue的响应式系统的一部分缓存其中的
}

mapGetters辅助函数

// mapGetters辅助函数仅仅是将store中的getter映射到局部计算属性:import {mapGetters} from 'vuex'export default {computed: {// 使用对象展开运算符将getter混入computed对象中...mapGetters(['doneTodoCount','anotherGetter',// 如果想要将getter属性取其他名字,使用对象形式doneCount: 'doneTodoCount'])}}

Mutation

// 更改vuex中的store的状态就是提交mutation,每个mutation都有一个字符串的事件类型type和一个回调函数handlerconst store = createStore({state: {count: 1},mutations: {increment(state,payload) {// 变更状态state.count += payload.amount}}
})组件,提交mutation的另一种方式是直接使用包含type属性的对象
store.commit('increment', {amount: 10
})store.commit({type: 'increment',amount: 10
})

使用常量替代Mutation事件类型

// mutation-types.jsexport const SOME_MUTATION = 'SOME_MUTATION'// store.jsimport {createStore} from 'vuex'import {SOME_MUTATION} from './mutation-types'const store = createStore({state:{...},// 我们可以用ES6风格计算属性命名功能// 使用一个常量作为一个函数名[SOME_MUTATION](state) {// 修改state}
})// Mutation必须是同步函数
mutations: {someMutation(state) {api.callAsyncMethod(() => {state.count++})}
}

现在想象,我们正在 debug 一个 app 并且观察 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools 都需要捕捉到前一状态和后一状态的快照。然而,在上面的例子中 mutation 中的异步函数中的回调让这不可能完成:因为当 mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用——实质上任何在回调函数中进行的状态的改变都是不可追踪的。---这段其实我现在看不太懂,等我后续研究了继续看。