我与Vuex的第一次邂逅
new Vue({ // state data () { return { count: 0 } }, // view template: ` <div>{{ count }}</div> `, // actions methods: { increment () { this.count++ } } })
上面是我们定义的一个vue的实例
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
what is 状态管理模式?
状态管理模式
1:state:驱动应用的数据源,比如组件当中的data就是数据源
2:view:以声明的方式将state映射到视图,比如组件上面的那些标签
3:actions:响应在视图view上面用户操作导致的状态变化,比如组件当中methods中的事件
//自己的理解,他们三有啥共同点? count,他们三都用到了这个值,如果只是单个组件中用到这个值,那么还可以控制,如果是多个组件同时用到这个数据呢?
//store就是将这些共享的状态抽出来,用一个全局单例模式进行管理
重点:全局--表示所有的组件都可以访问
:单例--表示Vuex只有一个实例
//这是一个store的实例,暂时还没有加入模块 export default new Vuex.Store({ state, getters, mutations, actions, })
构造器选项的解析:
state:类型为对象或者函数,如果是对象的话就会被当做根state,如果传入的是一个返回对象的函数,那么返回的对象作为根state 作用:存放数据 全局访问 this.$store.state--将store注入到了根节点的情况 //state对象属性可以定义成所有数据类型 const state = { userInfo: { phone: 111 }, //用户信息 orderList: [{ orderno: '1111' }], //订单列表 orderDetail: null, //订单产品详情 login: false, //是否登录 numver:1, myfunction:function() { console.log(arguments); }, }
当我们组件需要使用这个状态的时候,并且随着状态改变,组件的视图也会改变,那么最简单的方式就是在计算属性中返回某个状态 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return this.$store.state.count } } } //待续...如果组件需要多个状态呢?十个状态就要写十个计算实属性吗?
打个比方,你返回了一个数组,但是我们需要的是排序后的数组,并且多个组件都需要这个排序后的数组,解决办法无非是每个组件都重新进行对数组排序,或者写一个公共的方法,然后每个组件都引用这个方法
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来(当通过属性访问的时候),且只有当它的依赖值发生了改变才会被重新计算,
注意:getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果
getters:{ [key: string]: Function },没错这货是对象,并且他的所有属性都必须为函数 const getters = { myFirstGetter:function(state,getters){ console.log(arguments); }, mysecondGetter:function(state,getters){ console.log(arguments); return function(param) { console.log(arguments) } } } 作用:定义计算属性 //是的,计算属性,只不过这些计算属性是依赖state里面的数据 原因:我们确实可以在组件中对state的数据进行操作,但是多个组件获取同一个状态,都要进行相同的操作呢,那还不如我们集中管理. 全局访问 this.$store.getters 重点:所有的处理函数总是接收state作为第一个参数 ,接收其他的getter作为第二个参数 getters里面的方法的调用方式: 1:以属性的形式访问store.getters.funName //不要带括号,不要带括号,不要带括号 2:以方法的形式访问store.getters.funName(param) //前提是这个定义的方法的返回值必须是个函数,且param是作为返回值函数的参数. 待续.... 但是函数的参数很奇怪啊
mutations:类型{ [type: string]: Function },一个又一个函数 官方文档解释 { [type: string](事件类型): Function(回调函数) } 作用:如果我们在各自的组件当中更改状态的话,那么必然导致其他的组件也会更新该状态,最后我们都不知道到底是谁在更新这个状态,所以采用mutations提交的形式进行状态更改的管理,像不像git提交代码的形式... 全局访问 this.$store._mutations 重点:所有的回调函数(也就是进行状态更改的地方)总是接收state(没错就是上面的那个state)作为第一个参数 mutations里面的方法调用方式: store.commit('funName')--这种是我们没有把store注入到根组件 this.$store.commit('funName') --这种是注入了根组件,那么在每一个子组件都可以这种方式 然后我们还可以传参数 this.$store.commit('funName',{}) 参数作为对象这样可以包含多个字段 还有一种方式,使用包含type属性的对象, this.$store.commit({type:'funName',key:value}) 重点:原则就是要记住 mutation 必须是同步函数
actions:类型{ [type: string]: Function },也是一个又一个函数, 官方文档解释 { [type: string](事件类型): Function(回调函数) }在回调函数当中,我们进行状态改变 全局访问 this.$store._actions actions里面的方法调用方式: store.dispatch('funName') 同理于mutations 重点:所有的处理函数总是接收"context"作为第一个参数,他是一个对象... 一个与 store 实例具有相同方法和属性的对象 { //感觉好厉害的样式,但是暂时不知道有什么用 state, // 等同于 `store.state`,若在模块中则为局部状态 rootState, // 等同于 `store.state`,只存在于模块中 commit, // 等同于 `store.commit` dispatch, // 等同于 `store.dispatch` getters, // 等同于 `store.getters` rootGetters // 等同于 `store.getters`,只存在于模块中 } 重点:Action 与mutations的区别 1:Action 提交的是 mutation,而不是直接变更状态 2:Action 可以包含任意异步操作
Module:Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter 甚至于嵌套子模块,模块又是由几个模块组成 const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) 1:对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象 --state 2:对于模块内部的actions,局部状态通过 context.state暴露出来,根节点状态则为 context.rootState 3:对于模块内部的 getter,根节点状态会作为第三个参数暴露出来
不忘初心,不负梦想