vuex 实战 模板可套用 格式可套用

vuex.vue

 format:

import { resolve } from "dns";
import { reject } from "q";

const test = {
  // 共享数据源 data
  state: {
    userinfo: {},
    userList: [],
    departmentInfo: {},
    departmentList: [],
    sum: 0,
    substract: 0,
    multiply: 0,
    divide: 0,
    countPartA: 0,
    countPartB: 0
  },
  // 方法 methods
  mutations: {
    setUserInfo: (state, info) => {
      state.userinfo = Object.assign(info);
    },
    setDepartmentInfo: (state, info) => {
      state.departmentInfo = Object.assign(info);
    },
    setCountPartA: (state, info) => {
      state.countPartA = Number(info);
    },
    setCountPartB: (state, info) => {
      state.countPartB = Number(info);  
    }
  },
  // 计算属性 类似computed
  getters: {
    getSum: state => {
      return state.countPartA + state.countPartB;
    },
    getSubtract: state => {
      return state.countPartA - state.countPartB;
    },
    getMultiply: state => {
      return state.countPartA * state.countPartB;
    },
    getDivide: state => {
      return state.countPartA / state.countPartB;
    },
    // getter方法作为filter使用
    getAdultUser: state => {
      // 筛选年龄大于18岁的用户
      return state.userList.filter(userinfo => Number(userinfo.age) > 18);
    },
    // filter 实际是有三个参数的 => value, index, list
    getBabyUser: state => {
      return state.userList.filter((userinfo, index, list) => {
        Number(userinfo.age) < 2 &&
          Number(userinfo.age) > 0 &&
          index >= 0 &&
          list.length !== 0;
      });
    },
    // 接受getters作为第二参数,可以调用其他getter
    getOlderUser: (state, getters) => {
      return getters.getAdultUser.filter(userinfo => Number(userinfo.age) > 65);
    },
    // 接受外部传参
    getAdultBySex: (state, getters) => sex => {
      return getters.getAdultUser.filter(userinfo => userinfo.sex === sex);
    }
  },
  actions: {
    // 利用 context 本地资源对象
    asyncSetpartA: (context, info) => {
      setTimeout(() => {
        context.commit("setCountPartA", info);
      }, 1000);
    },
    // 接受多个参数
    asyncSetPartB: (context, { info, time }) => {
      setTimeout(() => {
        context.commit("setCountPartB", info);
      }, time);
    },
    /**
     *  context中包含的属性
     *  commit 调用mutation
     *  state
     *  dispatch 调用其他action
     */
    asyncSetChange: ({ dispatch }) => {
      dispatch("asyncSetpartA").then(() => {
        dispatch("asyncSetPartB");
      });
    },
    asyncSetChange2: ({ dispatch, state }) => {
      return new Promise((resolve, reject) => {
        dispatch("asyncSetPartB").then(() => {
          dispatch("asyncSetpartA").then(() => {
            if (state.sum !== 0) {
              resolve("done");
            } else {
              reject("no change");
            }
          });
        });
      });
    }
  }
};
/**
 *  vuex 若非必要,不建议使用
 *  1. 状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态
 *  2. store 中的状态改变的时候不能被vue中的data监听到
 *  3. Vuex中store数据改变的唯一方法就是mutation
 *  4. Action可以异步,Action 提交的是 mutation,而不是直接变更状态。
 *
 *
 *
 *  state 可以使用 mapState 在任意组件的computed中声明需要使用的数据
 *    ...mapState([  // 数组
 *      "userinfo",  // 如果使用同名引用,必须保证在state中此名字唯一
 *      "userList"
 *     ])
 *  或者
 *    ...mapStae({  // 对象
 *      depList: state => {   // 允许自定义名字,指向具体某个模块下的共享值
 *        return state.test.departmentList
 *      }
 *    })
 *    this.$store.state.userinfo // 单独引用
 *
 *
 *
 *  // mutations的调用方式唯一, 没有指定type的默认就是方法名
 *  // 第二个参数为方法所需参数, 如果需要多个参数,commit第二个参数就位一个对象,存放所有参数
 *  this.$store.commit("setCountPartB", info);
 *  作为对象提交
 *    this.$store.commit({
 *      type: "setCountPartB",
 *      info: info
 *    })
 *  // 使用 mapMutations 快速集成方法,一般在 methods 中声明使用
 *  ...mapMutations([
 *    "setUserInfo",
 *    "setDepartmentInfo"
 *  ])
 *  或者
 *  ...mapMutations({
 *    setA: "setCountPartA",
 *    setB: "setCountPartB"
 *  })
 *
 *
 *
 *  getters 可以使用 mapGetters 在任意组件的computed中声明使用
 *    ...mapGetters({
 *      getAdult: "getAdultUser"  // 这是对象
 *    })
 *  或者
 *    ...mapGetters([
 *      "getOlderUser" // 这是数组
 *    ])
 *    this.$store.getters.getBabyUser // 单独调用getter时不会创建缓存
 *    this.$store.getters.getAdultBySex("man") // 获取所有男性成年用户
 */
export default test;

example: vue + vuex

<template>
  <div>
    <span>用户信息:</span>
    <span>{{userInfo}}</span><br>
    <span>用户地址:</span>
    <span>{{address}}</span><br>
    <span>用户部门:</span>
    <span>{{department}}</span>
    <hr>
    <span>{{userDetails}}</span>
    <hr>
    <div style="display:flex;flex-direction:column;justify-content:center;align-items:center;">
      <input type="button" value="one year pass by!" @click="gettingOlder">
      <hr>
      <div>
        <input type="text" placeholder="entry your new name !" v-model="name">
        <input type="button" value="change name !" @click="changeUserName(name)">
      </div>
      <hr>
      <div>
        <input type="text" placeholder="entry a new street name !" v-model="str">
        <input type="button" value="change name !" @click="localFunChangeStrName(str)">
      </div>
      <hr>
      <input type="button" value="action" @click="localActionChangeData">
    </div>
  </div>
</template>
<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
  data () {
    return {
      name: '',
      str: ''
    }
  },
  methods: {
    ...mapMutations([
      'gettingOlder',
      'changeUserName'
    ]),
    // 使用传统的commit使用方法
    localFunChangeStrName (streetName) {
      this.$store.commit('changeStreet', streetName)
    },
    // 调用action
    localActionChangeData () {
      this.$store.dispatch('changeData').then(res => {
        console.log(res)
      })
    }
  },
  // state不能跨module注册,action , mutation , getter 可以被映射到根节点直接访问
  computed: {
    ...mapState({
      userInfo: (state) => { return state.localState.userInfo },
      address: (state) => { return state.localState.address },
      department: (state) => { return state.localState.department }
    }),
    ...mapGetters({
      userDetails: 'getUserInfo'
    })
  }
}
</script>
<style lang="less" scoped>
.test {
  justify-content: center;
  align-items: center;
}
</style>

state.js

const localState = {
  state: {
    address: {
      street: '江岸区五福路',
      city: '武汉市',
      country: '中国'
    },
    userInfo: {
      userName: '肖大洋',
      userAge: 31
    },
    department: [
      'development',
      'salor',
      'changeMan'
    ]
  },
  // vuex的同步methods,异步操作需要在action中完成
  mutations: {
    // 没有载荷的mutation
    gettingOlder (state) {
      console.log('gettingOlder')
      state.userInfo.userAge = state.userInfo.userAge + 1
    },
    // 拥有载荷的mutation
    changeUserName (state, payload) {
      console.log('changeUserName')
      state.userInfo.userName = payload
    },
    // 使用type版本的mutation方法在尝试中没有调用成功
    changeStreet (state, payload) {
      console.log('changeStreet')
      state.address.street = payload
    }
  },
  // vuex的计算属性computed => getters
  getters: {
    // 将getUserDepartment作为vuex的过滤器
    getUserDepartment: (state) => {
      state.department.forEach(item => {
        if (item === 'development') {
          return item
        }
      })
      return '没有'
    },
    getUserInfo: (state, getters) => {
      let userInfo = state.userInfo
      let address = state.address
      let department = getters.getUserDepartment
      let obj = { ...userInfo, ...address, department }
      return obj
    }
  },
  // 异步处理动作
  // 实测vue中无法将异步操作的结果通过resolve回传给调用方法的.then()
  actions: {
    // 异步操作
    async changeData ({commit, state}, payload) {
      // 等待数据更新完毕后弹窗
      await new Promise(function (resolve, reject) {
        setTimeout(function () {
          commit('gettingOlder')
          commit('changeUserName', '毛大和')
          commit('changeStreet', '湖北省武汉市')
        }, 3000)
      })
    }
  }
}

export default localState

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import count from './modules/count.js'
import localState from './modules/state.js'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  modules: {
    count,
    localState
  }
})

export default store

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值