Vuex笔记

Vuex

  1. 安装插件 Vue use(Vuex)
  2. 创建对象
 // index.js 笔记:
  import * as types './mutations-types'
  const store = new Vuex.Store({
    /**
      * 所有的数据响应式必须定义在state中
      */
    state: {
      count:0,
      students:[],
      info:{
        name:'xwg',
        age:18
      }
    },
    /**
     * mutations下的函数接收 state作为参数,接收一个叫做payload的(载荷)作为第二个参数,payload记录开发者使用该函数的一些信息
     * mutations方法必须是同步方法 不要在mutation中进行异步的操作
     * mutations中定义的函数可以看成两部分
     *    1、字符串的事件类型(type)
     *    2、一个回调函数(handler),该回调函数的第一个参数就是state
     */
    mutations: {
      //addStudent 事件类型
      //(state) {} 回调函数
      /**
        * 在页面中通过mutation更新 commit传入的第一个参数为事件类型 
        * this.$store.commit('addStudent',stu) //第一种写法
        * this.$store.commit({ //第二种写法
        *   type:'addStudent',
        *   stu 
        * })
        */
      addStudent(state,stu) {
        //第一种写法更新 这里的stu是一个学生对象
        state.students.push(stu) 
        //第二种写法更新 (stu更名为payload)这里的payload是包含事件类型的一个对象
        //payload.stu为学生对象
        state.students.push(payload.stu)
      },
      updateInfo(state){
        //非响应式
        state.info['address'] = '中国北京'

        //通过Vue.set实现响应式
        //Vue.set(state.info,'address','中国北京')

        //该删除对象属性方式做不到响应式
        //delete state.info.age

        //通过Vue.delete()实现响应式删除
        //Vue.delete(state.info,'age')
      },
      /**
        * 通过定义常量 避免mutations中定义的事件类型&页面commit提交时使用定义的常量不一致
        * 例:(前提先引入定义常量的js文件 import * as types './mutations-types')
        *   mutations:(index.js)
        *     [types.INCREMENT](state) {
        *       state.count++
        *     },
        *   页面中使用:(Home.vue)
        *     this.$store.commit(types.INCREMENT)
        */ 
      [types.INCREMENT](state){
        state.count++
      }
    },
    /**
      * 异步代码写在actions中
      */
    actions: {
      //context: 上下文 这里的context就是 store
      actUpdateInfo(context) {
        //模拟异步操作
        setTimeout(() => {
          //错误 
          //context.state.info['age'] = 26
          //正确
          context.commit('updateInfo')
          //在这里commit之后 页面(Home.vue)调用就不能够使用commit了,
          //应使用 this.$store.dispatch('actUpdateInfo') //通过dispatch调用actions中的方法
        })
      }
    },
    //模块
    modules: {
      moduleA
    }
  })

module是模块的意思,为什么在Vuex中我们要使用模块呢?

  • Vue使用单一状态树,那么也意味着很多状态都会交给Vuex来管理
  • 当应用变得非常复杂时,store对象就有可能变得相当臃肿
  • 为了解决这个问题,Vuex允许我们将store分割成模块(module),而每个模块拥有自己的state、mutations、actions、getters等
 const moduleA = {
   state: {
     name:'张三' 
     //页面中渲染 通过$store.state.moduleA.name实现,module中定义的state会放在store中的state
   },
   mutations: {
     updateName(state,payload) {
       state.name = payload
     }
     //正常调用(this.$stoer.commit('updateName','李四')) 如果store中的mutaions中找不到该方法则会到模块中(modules)查找
   },
   getters: {
     //页面正常调用 $store.getters.fullName
     fullName(state) {
       return state.name + '与李四的故事'
     },
     
     //第三个参数为store下的state
     fullName1(state,getters,rootState) {
       return getters.fullName + rootState.count
     }
   },
   actions: {
     //这里的context上下文 指的是当前模块
     //页面通过this.$store.dispatch('actUpdateName') 调用异步
     //另一种写法 利用对象的解构 actUpdateName({state,commit,rootState}){}
     actUpdateName(context) { 
       console.log(context) //state,commit,dispatch,rootGetters,rootState...
       setTimeout(() => {
         context.commit('updateName','王五')
       },1000)
     }
   }
 }

store中的每一项(mutations、getters、actions、modules)都可以单独拿出来放在单个js文件中

    //mutations-type.js

        // 通过定义常量 避免mutations中定义的事件类型&页面commit提交时使用定义的常量不一致
    /**
      * 例:(前提先引入当前的js文件 import * as types './mutations-types')
      *   mutations:(index.js)
      *     [types.INCREMENT](state) {
              state.counter++
           },
     页面中使用:(Home.vue)
      this.$store.commit(types.INCREMENT)
      */
      export const INCREMENT = 'increment'
      export const DECREMENT = 'decrement'
      export const CREMENTCOUNT = 'crementCount'
      export const ADDSTUDENT = 'addStudent'
      export const UPDATEINFO = 'updateInfo'
  //mutations.js
    
   import * as types from './mutations-type'
   export default {
     [types.INCREMENT](state) {
        state.counter++
     },
     [types.DECREMENT](state) {
        state.counter--
     },
     // mutations的(count) 参数被称为是mutation的载荷(payload)
     [types.CREMENTCOUNT](state,payload){
        console.log(payload)
        // state.counter += count
        state.counter += payload.count
     },
     [types.ADDSTUDENT](state,stu) {
        state.students.push(stu)
     },
     [types.UPDATEINFO](state) {
        state.info['name'] = '被改变的name值'
     }
   }
 //getters.js

    export default {
      // 基本使用 
      // 平方
      powerCounter(state) {
        return state.counter * state.counter
      },
      // 筛选年龄大于20的学生
      getStuToAge(state) {
        return state.students.filter(val => val.age > 20)
      },
      // 年龄大于20的学生个数  第二个参数固定就是getters 名称可自定义
      getStuToAgeNum(state, getrs) {
        return getrs.getStuToAge.length
      },

      moreAgeStu(state) {
        // 接收页面调用传过来的参数 返回一个function
        return age => {
          return state.students.filter(s => s.age > age)
        }
      }
    }
  //actions.js

    export default {
      // 异步操作
      // 页面中(Home.vue)调用actions中的方法通过 this.$store.dispatch('actUpdateInfo','参数')
      actUpdateInfo(context, payload) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            context.commit(types.UPDATEINFO)
            console.log(payload)
            resolve('修改完成')
          }, 1000)
        })
      }
    }

单独拿出来之后 最新的index.js

  import Vue from 'vue'
  import Vuex from 'vuex'

  import mutations from './mutations'
  import actions from './actions'
  import getters from './getters'
  import moduleA from './modules/moduleA'

  // 安装插件
  Vue.use(Vuex)

  const state = {
    counter:1000,
    students: [
      {id:101,name:'xwg',age:18},
      {id:102,name:'wpq',age:22},
      {id:103,name:'dyh',age:1},
      {id:104,name:'ddd',age:26}
    ],
    info:{
      name:'fexwg',
      age:18
    }
  }

  // 创建对象
  const store = new Vuex.Store({
    state,
    mutations,
    actions,
    getters,
    modules:{
      moduleA
    }
  })

  // 导出对象
  export default store
  1. 导出store对象 export default store

在Test.vue中使用vuex

  <template>
    <div>
      <h1>主页</h1>

      <h2>module中的内容</h2>
      <p>{{$store.state.moduleA.name}}</p>
      <button @click="changeModuleAname">改变module中的name值</button>

      <h3>{{$store.state.counter}}</h3>
      <button @click="add">加</button>
      <button @click="subtraction">减</button>
      <button @click="addCount(5)">加5</button>
      <button @click="addCount(10)">加10</button>
      <button @click="addStu">添加学生</button>

      <h2>getters相关信息</h2>
      <p>平方:{{$store.getters.powerCounter}}</p>

      <pre>
        <p>年龄大于20的学生对象:{{$store.getters.getStuToAge}}</p>
      </pre>
      <span>年龄大于20的学生个数:{{$store.getters.getStuToAgeNum}}</span>

      <pre>
        <p>根据页面传参返回学生对象:{{$store.getters.moreAgeStu(10)}}</p>
      </pre>

      <pre>
        <p>vuex中的info信息:{{$store.state.info}}</p>
      </pre>
      <button @click="updateInfo">改变info中的name值</button>

    </div>
  </template>

<script>
import * as types from '../../store/mutations-types'

export default {
  //import引入的组件需要注入到对象中才能使用
  components: {},
  data() {
    //这里存放数据
    return {};
  },
  //监听属性 类似于data概念
  computed: {},
  //监控data中的数据变化
  watch: {},
  //方法集合
  methods: {
    add() {
      this.$store.commit(types.INCREMENT)
    },
    subtraction() {
      this.$store.commit(types.DECREMENT)
    },
    addCount(count) {
      let obj = {
        count,
        name:'jack',
        sex:'man'
      }
      // this.$store.commit('crementCount',count)
      this.$store.commit({
        type:types.CREMENTCOUNT,
        ...obj
      })
    },
    addStu() {
      const stu = {
        id:105,
        name:'test',
        age:36
      }
      this.$store.commit(types.ADDSTUDENT,stu)
    },
    updateInfo(){
      // 同步操作
      // this.$store.commit(types.UPDATEINFO)
      // 异步操作
      // 调用mutation中的actions  通过dispatch
      this.$store.dispatch('actUpdateInfo','name值被异步操作改变了').then((ret) => {
        console.log(ret)
      })
    },
    changeModuleAname(){
      // 同步
      // this.$store.commit('updateName','李四')
      // 异步
      this.$store.dispatch('actUpdateName')
    }
  },
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {},
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {},
};
</script>
<style scoped>
</style>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • npminstallvuex--save 下载 主要可以分为 state getter mutation acti...
    hi_0eb6阅读 5,108评论 2 56
  • 一、什么是Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有...
    紫月凌枫阅读 10,138评论 0 16
  • 状态管理 当多个组件依赖于同一个数据时,比如购物车和结账,购物车需要作为全局变量,在整个单页面中需要调用的地方调用...
    艾满阅读 253评论 0 0
  • 介绍: 本文主要介绍vuex 中五个核心概念的基本用法,帮助对于不太看懂官方文档的同学 前提: 1. 熟悉vu...
    拉面的无聊时光阅读 650评论 0 1
  • 上一章总结了 Vuex 的框架原理,这一章我们将从 Vuex 的入口文件开始,分步骤阅读和解析源码。由于 Vuex...
    你的肖同学阅读 1,785评论 3 16