为了账号安全,请及时绑定邮箱和手机立即绑定

vuex全方位360度托马斯螺旋讲解

标签:
Vue.js vuex

首先什么是vuex,官网的解释是状态管理模式、集中式存储管理

###什么是状态管理模式:
状态即决定视图表现的数据,比如我们会在组件的data中定义一个numbe:1,那么我们就可以在组件中显示该数据,在Vuex中就被称为状态。一个组件中会定义很多个状态,这个时候就需要分类管理了,比如一个班级下面会有人数,性别等状态,如果把班级当作一个文件夹,那个人数,性别等状态就是该文件夹下面的文件,就出现了层级关系,这个就是状态树

###什么是集中式存储管理:
集中即代表不是分散的,不是各个组件单独维护自己的状态(在组件中使用 data配置项声明),而是集中管理,可以理解为一种响应式的全局变量,准确来说是要求应用建立并维护一个单一的、全应用范围共享的状态树

###什么时候要用到vuex:
vue里面是由一个又一个组件组成的,所以就存在组件中的通信,组件的通信有很多方法,但是如果不是简单的父子组件的通信,而是一个状态需要共享给多个组件时,就会非常麻烦,数据也会相当难维护

###什么是状态库:
Vuex的Store类 —— 状态库 —— 用于管理状态树,它的实例化配置项state 用来声明要创建的状态树,代码如下:

const store = new Vuex.Store({
  state:{ numner:0 }//state:存储状态。也就是变量
})

###如何使用状态库:
为了避免每个组件都要引入,我们可以在vue实例化的时候将状态库挂接为Vue实例的一个属性上

new Vue({
  store:store, //使用store配置项,就可以将状态库挂接为Vue实例 的属性$store
  template:'<ez-counter/>',
  components:{EzCounter}
})

###如何访问state里面的状态:

使用计算属性

computed: {
    number () {
      return this.$store.state.number
    }
  },

引入辅助函数mapState

//这里的state => state.number是es6里面的箭头函数相当于
//function(state) {
//  return state.number
//}
import { mapState } from 'vuex';
  export default {
    computed: {
        ...mapState({
          number : state => state.number ,
          number 1: state => state.number1
        })
    },

如果state里面定义的字段和页面要显示的字段是一样的话,也可以写成数组模式

...mapState([
    'number ',
    'number 1'
  ])

###什么时候使用getter:
getter:官方的解释是可复用的计算属性 —— 派生状态,说明白了也就是对state里面状态的进一步操作,比如数组的排序,过滤等,当多个组件需要这个功能的时候可以进行复用,可以理解为一个全局的公用函数,官方的例子如下:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
//对列表进行过滤
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  },
//Getter 也可以接受其他 getter 作为第二个参数:用来调用其他的getter
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
})

引入辅助函数mapGetters,方法和mapState一样,讲上面的mapState改成mapGetters就可以了

###什么是严格模式:
在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
开启严格模式,仅需在创建 store 的时候传入 strict: true

const store = new Vuex.Store({
  // ...
  strict: true
})

###什么是状态变更管理
Vuex要求组件将状态树视为只读,组件不应该直接修改状态树上的状态, 而是通过提申请的方式,由状态库来实际执行状态变更的操作:
state view mutation
在严格模式下,Vuex的状态约定为只读的,因此我们只能将其单向映射 为组件的只读计算属性,更改 Vuex 的 store 中的状态的唯一方法是提交 mutation

const store = new Vuex.Store({
  state:{number:0},
  mutations:{
    INCREASE(state,payload){ state.number= payload.num}
  }
})

这里可以传两个参数一个是state,另一个是提交的时候传过来的参数,可以是个字符串,也可以是个对象,如果这里需要接收多个参数,只能以对象的形式传,mutations里面的函数没有第三个参数,提交代码如下:

this.$store.commit('INCREASE', {
   num: 10
});
//也可以这样传,type为函数名,其他的都是传参
this.$store.commit({
  type: 'INCREASE',
  num: 10
})

这里可以使用 mapMutations 辅助函数,和之前的state,getter差不多,代码如下

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    //名字一样时可以用数组的形式
    ...mapMutations([
      'INCREASE'
      // `mapMutations` 也支持载荷:
      'INCREASE' // 将 `this.INCREASE(amount)` 映射为 `this.$store.commit('INCREASE', amount)`
    ]),
    ...mapMutations({
      add: 'INCREASE' // 也可以设置成想要的函数名称
    })
  }
}

然而mutation是同步的,不能写异步代码
###为什么要保证状态变更的同步性
Vuex作为一个状态管理系统,其核心特性就在于保证每一个状态变更(mutation)的 可跟踪性,异步代码会导致状态变更与应用状态的不一致,因而导致了应用状态的不可预测性。
我们在RESET变更处理器中加入了异步代码:

const store = new Vuex.Store({
  state:{ number:0},
  mutations:{
    reset: state => setTimeout(() => state.number= 0, 3000)
  }
})

当事件触发是状态counter被重置为0,
但现在的问题是当点击按钮的同时couter状态并没有马上变化,而是3秒钟后异步代码执行后才发生改变,这就导致不可预测,这个时候就引入了action
###如何使用action

const store = new Vuex.Store({
  state:{number:0},
  mutations:{
    INCREASE(state,payload){ state.number= payload.num}
  },
  actions:{
      //写法一
     add(context) {
         context.commit('INCREASE')
     }
     //写法二
     add({ commit }) {
       commit('INCREASE')
     }
})
// 这里用到了对象的结构
//因为函数的参数是一个对象,函数中用的是对象中一个方法,我们可以通过对象的
//解构赋值直接获取到该方法
//因为context本身就是一个对象,里面有state对象和commit方法例如
let context {
   state: {},
   commit: function(){}
}
//根据对象结构可以定义如下:
let {state,commit} = context
console.log(state)//state: {};
console.log(commit)//commit: function(){};
//所以放在函数里面就是
add({state,commit} ) {
     commit('INCREASE')
  }

调用this.$store.dispatch(‘add’)
###如何使用Module
由于将整个应用的状态保存在单一的状态树中,对于复杂的应用而言, 这个状态树将相当的大。因此,Vuex允许我们将状态树拆分为状态管理模块(module)
例如,下面定义了两个状态模块modCounter和modClock:

const add= {
  state:{number:0},
  mutations:{ INCREASE(state){state.number++} }
}

const add1 = {
  state:{number1:0},
  mutations:{ADD(state,val){state.time = val}}
}
const store = new Vuex.Store({
  modules:{
    a1:add,
    a2: add1 
  }
})

访问模块的状态

 //访问a1模块的number1状态,
console.log(this.$store.state.a1.number1)
//访问a2模块的number2状态。
console.log(this.$store.state.a2.number2) 
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
1
获赞与收藏
12

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 1
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消