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>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

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