vue store

vuex实际项目中的应用实例:

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

import Base64 from '../common/base64.js';
import {
    request,
    getUserInfo,
    getCartlist
} from "../common/utils.js";

Vue.use(Vuex)

/**
 * 登录失效移除token
 */
function removeAccesstoken(res) {
    if (res && res.code == 401) {
        uni.removeStorageSync('access_token');
        uni.removeStorageSync('cartNumber');
    }
}

/**
 * vuex 状态管理
 */
const store = new Vuex.Store({
    state: {
        userinfo: {},
        nickName: "",
        userRank: 0,
        balance: 0,
        isLogin: false,
        cartNumber: 0,
        access_token: '',
        // 
        addressId: 0,
        couponId: 0,
        orderViewCoupon: null,
        coudanInfo: null,
        //客服聊天
        user: {
            home: {
                id: 1,
                name: 'tax',
                img: '/static/images/logo.png'
            },
            customer: {
                id: 2,
                name: 'customer',
                img: '/static/images/public/img_user@2x.png'
            }
        }
    },
    updated: function() {},
    mutations: {
        // 更新用户信息
        updateUserInfo(state, value) {
            state.userinfo = value;
        },
        // 更新用户昵称
        updateNickName(state, value) {
            state.nickName = value;
        },
        // 更新用户是否VIP
        updateUserRank(state, value) {
            state.userRank = value;
        },
        // 更新用户积分
        updateBalance(state, value) {
            state.balance = value;
        },
        // 更新全局购物车数量
        updateCart(state, value) {
            state.cartNumber = value;
            uni.setStorageSync('cartNumber', value);
        },
        // 更新用户在线token
        updateToken(state, value) {
            state.access_token = value;
        },
        // 更新用户确认订单去使用优惠券
        updateCoupon(state, list) {
            state.orderViewCoupon = list;
        },
        // 更新用户确认订单使用优惠券ID
        updateCouponId(state, couponId) {
            state.couponId = couponId;
        },
        // 更新用户确认订单使用优惠券ID
        updateAddressId(state, addressId) {
            state.addressId = addressId;
        },
        // 更新用户凑单 => 已经更新为使用缓存机制
        updateCoudan(state, list) {
            state.coudanInfo = list;
        },
        login(state, message) {
            state.isLogin = message;
        }
    },
    actions: {
        // 首页获取用户信息,提供给模块判断是否登录授权
        getUserInfos: async function({
            commit,
            state
        }) {
            let res = await request({
                access_token: state.access_token ? state.access_token : '',
                url: getUserInfo,
                isNot: true
            });
            if (res && res.data) {
                // console.log(res,'+++++')
                let {
                    nickName,
                    userRank,
                    balance,
                    access_token,
                    is_checked
                } = res.data;
                let token = `Basic ${Base64.encode(access_token+':')}`
                commit('updateNickName', nickName);
                commit('updateUserRank', userRank);
                commit('updateBalance', balance);
                commit('updateToken', token);
              
                uni.setStorageSync('userinfo', res.data);
                uni.setStorageSync('is_checked', is_checked);
                // uni.setStorageSync('is_checked', 0);
            } else {
                removeAccesstoken(res);
            }
        },
        // 首页获取用户信息,提供给模块min导航显示购物车数量
        getCartInfo: async function({
            commit,
            state
        }) {
            let res = await request({
                access_token: state.access_token ? state.access_token : '',
                url: getCartlist,
                isNot: true
            });
            if (res && res.data) {
                let total = res.data.total;
                commit('updateCart', total.totalCount);
            } else {
                removeAccesstoken(res);
            }
        }
    }
})

export default store


vuex 包含有五个基本的对象:

state:存储状态。也就是变量;
getters:派生状态。也就是set、get中的get,有两个可选参数:state、getters分别可以获取state中的变量和其他的getters。外部调用方式:store.getters.personInfo()。就和vue的computed差不多;
mutations:提交状态修改。也就是set、get中的set,这是vuex中唯一修改state的方式,但不支持异步操作。第一个参数默认是state。外部调用方式:store.commit('SET_AGE', 18)。和vue中的methods类似。
actions:和mutations类似。不过actions支持异步操作。第一个参数默认是和store具有相同参数属性的对象。外部调用方式:store.dispatch('nameAsyn')。
modules:store的子模块,内容就相当于是store的一个实例。调用方式和前面介绍的相似,只是要加上当前子模块名,如:store.a.getters.xxx()。
二: Vuex HelloWorld
2.1 Vuex安装
cnpm install vuex --save
1
显式使用Vuex插件,一般写在src/main.js中,或者写在其它js中然后再在main.js中引入

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

Vue.use(Vuex)

2.2 多组件共享全局状态示例
分别在Foo.vue和Bar.vue中改变全局属性count值,然后在App.vue中显示count修改后的值。

定义全局单例对象 src/store/store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  },

  mutations: {
    increment (state, payload) {
      state.count += payload.step
    },
    decrement: state => state.count--,
  }
})

定义一个全局实例对象(Vuex.Store):

该对象的状态(state)就是全局属性, 类似于组件的data,每个组件都可以访问和修改属性。

可变的(mutations)类似于组件中的methods, mutations中的每个方法称作为 mutation handler,用来修改state中的值,方法的参数可以有两个(state, payload) state表示全局的单例对象,payload(载荷)也就是参数,调用时可以传递参数,该参数是可选的。

使用Mutation时需遵守的一些规则:

最好提前在你的 store 中初始化好所有所需属性。

当需要在对象上添加新属性时,你应该使用 Vue.set(obj, ‘newProp’, 123), 或者以新对象替换老对象

Mutation 必须是同步函数

在src/main.js中导入store.js并作为Vue的选项
import Vue from 'vue'
import App from './App'
import router from './router'

import store from './store/store'

Vue.config.productionTip = false


/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  router,
  components: { App },
  template: '<App/>'
})

将store作为Vue的选项,这样Vue会将store“注入”到每一个子组件中,也就是说每个组件都可以通过this.$store来访问全局单例对象store。

Foo.vue
<template>
  <div>
    Foo.vue <button @click="increment">+</button>
  </div>
</template>

<script>
  export default {
    name: 'Foo',
    methods: {
      increment () {
        this.$store.commit('increment', {
          step: 10
        })
      }
    }
  }
</script>

调用store中的mutations方法只能通过提交的方式this.$store.commit('方法名', 负载参数)这一种形式来调用,而不能使用this.$store.方法名 这种普通的的 对象.方法() 方式直接调用。如果感觉这种方式麻烦,Vuex提供了一种将Mutations映射(map)为methods的方式, 然后在使用时直接调用method就会自动帮你commit。

mapMutations() 函数,它接收一个参数,参数类型可以是数组也可以是对象:

数组类型:当使用方法时方法名称和Mutation的名称一样时使用数组类型。
对象类型:当使用方法时方法名称不想和Mutation的名称一样,可以对method起一个新的名称
<template>
  <div>
    Foo.vue <button @click="add({step: 10})">+</button>
  </div>
</template>

<script>
  import { mapMutations } from 'vuex'

  export default {
    name: 'Foo',
    methods: {
      // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
      // 将 `this.incrementBy({step: 10})` 映射为 `this.$store.commit('incrementBy', {step: 10})`
      ...mapMutations(['increment', 'incrementBy']),
      
      // 将Mutation(increment)映射为method(add)
      ...mapMutations({
        add: 'increment'
      })
    }
  }
</script>

注意:mapMutations只是将Mutations简单的映射为methods, 其中method的方法体只包含this.$store.commit(‘mutation’, payload)这一样代码,如果method还要处理其它业务逻辑的话,那么只能使用提交commit方式,而不能使用映射方式mapMutations。

Bar.vue
<template>
    <div>
      Bar.vue <button @click="decrement">-</button>
    </div>
</template>

<script>
  export default {
    name: 'Bar',
    methods: {
      decrement () {
        this.$store.commit('decrement')
      }
    }
  }
</script>

App.vue
<template>
  <div id="app">
    App.vue {{count}}
    <router-view name="foo"></router-view>
    <router-view name="bar"></router-view>
  </div>
</template>

<script>
  export default {
    name: 'App',
    computed: {
      count() {
        return this.$store.state.count
      }
    }
  }
</script>

可以通过{{ this.$store.state.count }}来获取count的值,也可以将this.$store.state.count这行代码包装到计算属性count中,这样获取值就方便点{{ count }}。

src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'

import Foo from '../components/Foo'
import Bar from '../components/Bar'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      components: {
        foo: Foo,
        bar: Bar
      }
    }
  ]
})

为了在一个组件中使用多个兄弟组件,使用命名视图,将这些兄弟组件作为父组件的孩子组件。

2.3 actions
Action 类似于 mutation,Action用于分发(dispatch)mutation,而不直接修改状态。 Action 可以包含任意异步操作(如发送http请求)

action方法接收两个参数(context, payload),context为Context对象,context对象store实例具有相同方法和属性,所以context可以解构成var {state, dispatch, commit, getters} = context

src/store/store.js

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  },

  mutations: {
    increment (state, payload) {
      state.count += payload.step
    },
    decrement: state => state.count--,
  },

  actions: {
    incrementAsync (context, payload) {
      console.log(context.state)
      console.log(context.getters)

      // 延迟1秒执行
      setTimeout(() => {
        context.commit('increment', payload)
      }, 1000)
    }
  }
})

Foo.vue

<template>
  <div>
    Foo.vue <button @click="increment">+</button>
  </div>
</template>

<script>

  export default {
    name: 'Foo',
    methods: {
      increment () {
        this.$store.dispatch('incrementAsync', { step: 10 })
      }
    }
  }
</script>

原文链接:https://blog.csdn.net/sunlizhen/article/details/90231879

原文地址:https://www.cnblogs.com/zwjun/p/12656251.html