vuex的使用

2 篇文章 0 订阅
2 篇文章 0 订阅

官方文档地址:https://vuex.vuejs.org/zh/

官方文档已经很完善,推荐不熟悉vuex的同学可以多多阅读官方文档

vuex是vue的一个全局状态管理工具,一般作为vue的全局数据存储中心

1.常规使用

store.js中

import Vue from 'vue'
import Vuex from 'vuex'
 
Vue.use(Vuex)
 
const store = new Vuex.Store({
  state: {
    count: 0
  },
  getters: {
    getCountString(state) {
      return state.count + ''
    }
  },
  mutations: {
    setCount (state, data) {
      state.count = data
    }
  },
  actions: {
    setCountAsync(store, data) {
      setTimeout(()=>{
        store.commit('setCount', data)
      }, 500)
    }
  }
})
 
 
export default store

如上所示,作为数据管理器,store存在set与get方法
其中

set方法即为store配置项中的mutations与actions
get方法为getters与state

任意vue页面中使用

<template>
  <div id="app">
    {{ count }}
  </div>
</template>
<script>
import { mapState,mapGetters,mapActions, mapMutations } from 'vuex'
export default {
  name: "app",
  computed: {
    ...mapState(['count']),
    ...mapGetters(['getCountString'])
  },
  methods: {
    ...mapMutations(['setCount']),
    ...mapActions(['setCountAsync']),
  }
};
</script>

在以上代码中,可以在当前页面的实例中

通过this.count获取vuex中的count

通过this.getCountString获取count的字符串形式

通过this.setCount(n)将count设置为n

通过this.setCountAsync(n)将count异步设置为n

mapState,mapGetters,mapActions, mapMutations为vuex提供的辅助函数,可以将vuex中对应键名的数据或函数挂载到当前实例,通过this访问

当键名发生冲突时也可以另外映射

...mapMutations({
    changeCount: 'setCount'
})

该句意为将this.$store.commit(‘setCount’, n )映射为this.changeCount(n)
actions相同
通常不建议重命名,会导致代码追溯困难

不使用辅助函数时,也可以这样使用

this.$store.state.count
this.$store.getters.getCountString
this.$store.commit('setCount', n )
this.$store.dispatch('setCountAsync', n)

在独立js中,可将store.js引入
用store代替this.$store即可

在vue中推荐使用辅助函数,在一个页面需要多处用到store数据时方便管理

2.项目中使用

持久化
在项目中,由于store会在刷新后重置,我们需要考虑持久化的场景,这时候可以考虑通过
vuex-persist
进行数据的持久化
yarn add vuex-persist
or
npm install vuex-persist
使用时,需考虑对低版本浏览器的兼容,即配置babel编译目录包括该目录,具体配置如下

高版本cli, vue.config.js中

// in your vue.config.js
module.exports = {
  /* ... other config ... */
  transpileDependencies: ['vuex-persist']
}

低版本cli, build/webpack.config.js中

module.exports = {
    /* ... other config ... */
    module: {
        rules: [
        {
            test: /\.js$/,
            loader: 'babel-loader',
            include: [resolve('src'),  resolve('vuex-persist')]
        }]
    }
}

需注意,持久化方案一般为将数据json化后存储到sessionStorage或localStorage
故此方案只支持可以json化的数据类型的持久化,当store中存在复杂数据类型,如socket等对象时
需考虑初始化方案

模块化
在稍大的项目中,当vuex中存放的数据达到几十甚至上百条时,这时使用单一的state已经很难去管理了,维护起来也很困难,这种情况就需要进行模块化了

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import VuexPersist from "vuex-persist";
import user from './user'
Vue.use(Vuex);
const VuexLocal = new VuexPersist({
  modules: ['user'],
  storage: sessionStorage
});
 
 
export default new Vuex.Store({
  modules: {
    user
  },
  plugins: [VuexLocal.plugin]
})

user.js

import { ayList } from "@/api/judge"
import { treeToList } from "@/utils/tool"
export default {
  namespaced: true,
  state: {
    token: '',
    userInfo: {},
    menuTree: [],
    menuList: [],
    ayList: [],
  },
  mutations: {
    updateToken(state, data = '') {
      state.token = data
    },
    updateUserInfo(state, data = {}) {
      state.userInfo = data
    },
    updateMenuTree(state, data = []) {
      state.menuTree = data
      state.menuList = treeToList(data)
    },
    updateAyList(state, data = []) {
      state.ayList = data
    },
    clearUser(state) {
      // 保持数据类型一致
      for (const key in state) {
        if (typeof state[key] == "object") {
          if (Array.isArray(state[key])) {
            state[key] = []
          } else {
            state[key] = {}
          }
        } else {
          state[key] = ""
        }
      }
    }
  },
  actions: {
    setAyList(store) {
      let userId = store.state.userInfo.userId
      ayList({
        userId
      }).then(res => {
        const ayList = res.data.map(i => ({ value: i, label: i }))
        store.commit('updateAyList', ayList)
      })
    },
  }
}

其中,ayList返回值为Promise对象,为异步方法
注意,模块化的情况下,需将模块化的namespaced值为true, 方便管理追踪

在vue中使用

<template>
  <div id="app">
    {{ userInfo.name }}
  </div>
</template>
<script>
import { createNamespacedHelpers } from "vuex";
const { mapState: mapUserState, mapMutations: mapUserMutations, mapActions: mapUserActions } = createNamespacedHelpers("user");
export default {
  name: "app",
  computed: {
    ...mapUserState(['userInfo','ayList']),
  },
  created() {
    this.init()
    this.read()
  },
  methods: {
    ...mapUserMutations(['updateUserInfo']),
    ...mapUserActions(['setAyList']),
    init() {
      this.setAyList()
      this.updateUserInfo({userName: 'ssc',userId: 1})
      console.log(this.userInfo)
      console.log(this.ayList)
    },
    read() {
      this.$store.dispatch('user/setAyList')
      this.$store.commit('user/updateUserInfo', {userName: 'ssc',userId: 1})
      console.log(this.userInfo)
      console.log(this.ayList)
    },
    reset() {
      this.$store.commit('user/clearUser')
    }
  },
};
</script>

以上为vuex的基本用法,更多用法可查看官网

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值