美文网首页
Vuex笔记

Vuex笔记

作者: FE晓伟哥 | 来源:发表于2020-11-12 09:20 被阅读0次

    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>
    

    相关文章

      网友评论

          本文标题:Vuex笔记

          本文链接:https://www.haomeiwen.com/subject/kungvktx.html