Vue 生态篇(一)
为什么需要Vuex
单向数据流
整个系统运行是一个单向的,数据State去驱动视图View的更新,用户在视图View上进行一些操作触发Actions,通过Actions的方式再去更改数据State
状态管理
下图组件E、F、I都需要显示用户名称userName,当这个名称被修改时,这些组件都需要同步更新userName,那如何进行userName状态管理呢?
方式一:通过组件层层传递方式,在组件E、F、I的共同父组件A上进行管理。这种方式比较脆弱,而且成本比较高。
方式二:Provide/Inject,避免了层层传递的繁琐,但它还是与组件强相关,需要在组件中提供数据,对于小型状态管理是个不错的方案,但当状态数比较大时,需要一个更加系统化的状态管理工具。
方式三:Vuex,不仅仅是提供响应式数据,还可以动态注册响应式数据,用命名空间来管理数据,通过插件记录数据的更改便于调试。
Vuex运行机制
下图绿色框中是Vuex要做的事情,它不再与组件强相关,可以独立提供响应式数据。
Vuex整个运行机制也是个单向数据流。
Vuex提供数据State来驱动视图组件Vue Components,视图组件通过Dispatch来派发Actions。在Actions中可以进一步做些异步操作(如Backend API请求后端接口),然后通过Commit形式提交给Mutations,Mutations最终来更改数据State。经过一层Mutations,主要是为了在插件Devtools中记录数据的变化,这样可以在插件Devtools中进行调试。整个过程中,Mutations是纯同步操作到Devtools,异步操作需要在Actions中进行,如果没有异步操作,可以直接从视图组件Commit到Mutations。
如何在Vue中使用Vuex
state:数据是响应式的
getters:类似于组件中的计算属性,方便缓存某个数据
Vuex的acitons应该避免直接操作state,state的更改应该由mutations去修改,不然vue-devtools插件记录不到state的变更。actions可以更具当前state进一步处理数据,计算或请求后端接口,然后通过commit的形式提交给mutations去处理。
action函数接受一个与 store 实例具有相同方法和属性的 context 对象。
Vuex核心概念及底层原理
State —— this.$store.state.xxx 取值
提供一个响应式数据
Getter —— this.$store.getters.xxx 取值
借助Vue的计算属性computed来实现缓存
Mutation —— this.$store.commit(“xxx”) 赋值
更改state方法
Action —— this.$store.dispatch(“xxx”) 赋值
触发mutation方法,不能直接修改值,还是需要commit
Module 模块化,状态辅助管理。Vue.set动态添加state到响应式数据中。
Store 是如何做到我们的一个响应式的?
实际上它还是利用了 Vue,通过 new Vue()
函数构建了一个 Vue 实例,并将 state
存放在了这个实例的响应式数据 data里面。这样的话,state
已经变成了一个间接的响应式数据。
通过Object.defineProperties(Store.prototype, {......})重写了state的getter
函数。get
函数返回一个 _vm
实例下的数据 data
中的 $$state
属性,其实就是 Store
对象下的 state
对象,只不过从 _vm
实例中取了一遍,就编程响应式的了。
Vuex最佳实践
核心概念
State —— this.$store.state.xxx 取值 —— mapState 取值
Getter —— this.$store.getters.xxx 取值 —— mapGetter 取值
Mutation —— this.$store.commit(“xxx”) —— mapMutations 赋值
Action —— this.$store.dispatch(“xxx”) 赋值 —— mapAction 赋值
Module 模块化,状态辅助管理。
Module
开启命名空间 namespaced:true
潜逃模版不要过深,尽量扁平化
灵活应用 createNamespacedHelpers
评论