zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Linux上传下载文件(rz/sz)
    注册页面(函数调用,数组,对象,for,innerHTML)
    课程表(点击事件,for)
    winform中固定界面大小的方法
    VS常用快捷键
    Python的标准输出
    Spring注解驱动第二讲--@ComponentScan扫描介绍
    Spring注解驱动第一讲--Spring环境搭建
    通用目标检测
    通用目标检测-发展趋势
  • 原文地址:https://www.cnblogs.com/zwjun/p/12656251.html
Copyright © 2011-2022 走看看