Vuex笔记

2020-11-12  本文已影响0人  FE晓伟哥

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中我们要使用模块呢?

 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>
上一篇下一篇

猜你喜欢

热点阅读