如何使用vuex

Vuex是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。多个组件共享状态,不同视图的行为需要变更同一状态时候则需要用到Vuex。

Vuex的五个概念

  • state:定义共用的状态数据
  • getters:根据state计算新的属性(类似于computed)
  • actions:发起异步请求
  • mutations:定义修改状态数据的方法
  • modules:拆分模块

在项目中如何使用Vuex

1.下载安装vuex

npm install vuex -S

2.新建store目录,在store目录下新建index.js(目录和文件名随意)

在index.js中开始编写代码:

import Vue from 'vue'
import Vuex from 'vuex'
//插件,需要use
Vue.use(Vuex)

//定义共用的状态数据
const state = {
    count: 0
}

export default new Vuex.Store({
    state
})

 在main.js中配置store

import Vue from 'vue'
import App from './App.vue'
import store from '../src/store/index' //+

Vue.config.productionTip = false

let vm = new Vue({
  render: h => h(App),
  store //+ 注入store,在任何组件中都可以通过$store对象操作状态
})

vm.$mount('#app')

在组件中使用state中的状态数据

<template>
  <div id="app">
       state.count:{{$store.state.count}} 
  </div>
</template>

结果:

 在任意组件中获取state中的数据都可以用过this.$store.state来获取

3.修改state状态数据(mutations和actions)

通过dispatch分发事件
语法:this.$store.dispatch('事件名称', payload)
事件名称:actions中定义的函数名字

从文章的第一张图片可以看出,actions通过commit把事件提交给
mutations修改状态数据
具体语法:actions = {
    函数({commit, state}[, payload]) {
        xxx
        commit('mutations事件名称'[,payload])
    }
} 

mutations = {
    函数(state[,payload]) {
        xxxx
    }
}


payload是载荷,可选参数,传入的参数

为什么要有actions和mutations,只用mutations不行吗?
actio提交的是mutation,而不是直接变更状态
在mutation中只能执行同步代码,不能使用异步
而在action中可以使用任意的异步代码,不受约束
所以要存在actions和mutations

// 假设 getData() 和 getOtherData() 返回的是 Promise

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

例子:

首先修改组件中的代码:

<template>
  <div id="app">
    state.count:{{$store.state.count}} <br />
    {{$store.getters.odd_even}} <br />
    <button @click="add">count+1</button>&nbsp;&nbsp;
    <button @click="increment">count-1</button>&nbsp;&nbsp;
    <button @click="delayAdd">count延迟1秒+1</button>
  </div>
</template>

<script>

export default {
  methods: {
    add() {
      this.$store.dispatch('add')
    },
    increment() {
      this.$store.dispatch('increment')
    },
    delayAdd() {
      this.$store.dispatch('delayAdd')
    }
  }
}
</script>

修改store/inde.js

import Vue from 'Vue'
import Vuex from 'Vuex'
//插件,需要use
Vue.use(Vuex)

const state = {
    count: 0
}

//定义mutation
const mutations = {
    ADD(state) {
        //修改state中的数据
        state.count++
    },
    INCREMENT(state) {
        state.count--
    }
}

//定义action
const actions = {
    add({commit}) {
        //提交mutation
        commit('ADD')
    },
    increment({commit}) {
        commit('INCREMENT')
    },
    delayAdd({commit}) {
        setTimeout(() => {
            commit('ADD')
        },1000)
    }
}

export default new Vuex.Store({
    state,
    actions,
    mutations
})

4.派生状态getters

语法:
getters = {
    getter名字(state) {
       xxxx
       return 返回的值
    }
}

例子:页面显示state.count是奇数还是偶数

//在组件中添加:
{{$store.getters.odd_even}} <br />

//在store/index.js添加
const getters = {
    odd_even: (state) => {
        return state.count % 2 ===0 ? '偶数' : '奇数'
    }
}

export default new Vuex.Store({
    state,
    getters, //+
    actions,
    mutations
})

整体效果:

 5.mapState、mapActions、mapGetters辅助函数的使用

  • mapState:当一个组件需要获取多个状态的时候,将这些属性声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用mapState辅助函数帮助我们生成计算属性。
  • mapActions:使用mapActions辅助函数将组件的methods映射为methods中的方法
  • mapGetters:使用mapGetters辅助函数将store中的getter映射到局部计算属性

案例:

<template>
  <div id="app">
    state.count:{{$store.state.count}} <br />
    {{$store.getters.odd_even}} <br />
    <!-- 7.mapActions -->
    <button @click="add">count+1</button>&nbsp;&nbsp;
    <button @click="increment">count-1</button>&nbsp;&nbsp;
    <button @click="delayAdd2">count延迟1秒+1</button>
    <hr />
    <!-- 3.mapState -->
    <h3>count: {{count}}</h3>
    <h3>selfCount: {{selfCount}}</h3>
    <h3>countPlus: {{countPlus}}</h3>
    <!-- 5.mapGetters -->
    <h3>oddorEven: {{oddorEven}}</h3>
  </div>
</template>

<script>
import {mapState, mapGetters, mapActions} from 'vuex' //1.引入辅助函数
export default {
  data() {
    return {
      num: 10
    }
  },
  computed:{
    //2.使用mapState生成计算属性
    //三种方法:
    ...mapState({
      //使用函数返回state的属性
      count:state => state.count,
      //起别名,直接写state中的变量名,以字符串形式
      selfCount: 'count',
      //可以写表达式
      countPlus() {
        return this.count + this.num
      }
    }),
    //4.mapGetters
    /** 
     * computed: {
     *    ...mapGetters(['xxx']),
     *    ...mapGetters({新名字: 'xxx'})
     * }
     * 备注:xxx是getter的名字
    */
    ...mapGetters({
        oddorEven: 'odd_even'
    })
  },
  methods: {
    //6.mapActions
    /**
     * ...mapActions(['xxx', 'xxx2'])
     * ...mapActions({新名字: 'xxx'})
     * 备注:xxx,xxx2是actions中定义的函数名称
    */
    ...mapActions(['add', 'increment']),
    ...mapActions({
      delayAdd2: 'delayAdd'
    })
  }
}
</script>

6.模块化

在Vue中State使用的是单一状态树结构,应该所有的状态都放在State里面,如果项目比较复杂,state是一个人很大的对象,stroe对象也将会变得复杂难以管理。module模块化可以让每个模块拥有自己的state、mutations、actions、getters,让结构更为清晰,便于项目的管理。

export default new Vuex.Store({
  state:{}, //公用的数据
  getters:{},
  mutations:{},
  actions:{},
  modules:{
    模块名1:{
      /*如果namespace为false(默认是false),state可以通过模块获得,
      actions、getters、mutations依然是全局的,无法通过模块获得*/
      namespace:true,
      state:{},
      getters:{},
      mutations:{},
      actions:{},
    },
    模块名2:{
      namespace:true,
      state:{},
      getters:{},
      mutations:{},
      actions:{},
    },
  }
})

//通过this.$store.state.模块名.属性名获取模块的state
//通过this.$store.dispatch('模块名/action')修改state
//通过this.$store.getter['模块名/getter']获取getter

/**
 * 模块中使用辅助函数
 * ...mapState('模块名',{
 * })
 * ...mapGetters('模块名', {
 * })
 * ...mapActions('模块名',{
 * })
*/

修改上面的案例,添加test模块:

  • 修改store/index.js
import Vue from 'Vue'
import Vuex from 'Vuex'
//插件,需要use
Vue.use(Vuex)

const state = {
    count: 0
}

const getters = {
    odd_even: (state) => {
        return state.count % 2 ===0 ? '偶数' : '奇数'
    }
}

const mutations = {
    ADD(state) {
        state.count++
    },
    INCREMENT(state) {
        state.count--
    }
}

const actions = {
    add({commit}) {
        commit('ADD')
    },
    increment({commit}) {
        commit('INCREMENT')
    },
    delayAdd({commit}) {
        setTimeout(() => {
            commit('ADD')
        },1000)
    }
}

export default new Vuex.Store({
    state:{},
    getters:{},
    actions:{},
    mutations:{},
    modules:{
        test:{//添加模块
            namespaced: true,
            state,
            actions,
            mutations,
            getters
        }
    }
})


  • 修改组件中的代码:
<template>
  <div id="app">
    state.count:{{$store.state.test.count}} <br /><!--变动-->
    {{$store.getters['test/odd_even']}} <br /> <!--变动-->
    <!-- 7.mapActions -->
    <button @click="add">count+1</button>&nbsp;&nbsp;
    <button @click="increment">count-1</button>&nbsp;&nbsp;
    <button @click="delayAdd2">count延迟1秒+1</button>
    <hr />
    <!-- 3.mapState -->
    <h3>count: {{count}}</h3>
    <h3>selfCount: {{selfCount}}</h3>
    <h3>countPlus: {{countPlus}}</h3>
    <!-- 5.mapGetters -->
    <h3>oddorEven: {{oddorEven}}</h3>
  </div>
</template>

<script>
import {mapState, mapGetters, mapActions} from 'vuex' //1.引入辅助函数
export default {
  data() {
    return {
      num: 10
    }
  },
  computed:{
    //2.使用mapState生成计算属性
    //三种方法:
    ...mapState('test', {//变动,添加test模块
      //使用函数返回state的属性
      count:state => state.count,
      //起别名,直接写state中的变量名,以字符串形式
      selfCount: 'count',
      //可以写表达式
      countPlus() {
        return this.count + this.num
      }
    }),
    //4.mapGetters
    /** 
     * computed: {
     *    ...mapGetters(['xxx']),
     *    ...mapGetters({新名字: 'xxx'})
     * }
     * 备注:xxx是getter的名字
    */
    ...mapGetters('test', {//变动,添加test模块
        oddorEven: 'odd_even'
    })
  },
  methods: {
    //6.mapActions
    /**
     * ...mapActions(['xxx', 'xxx2'])
     * ...mapActions({新名字: 'xxx'})
     * 备注:xxx,xxx2是actions中定义的函数名称
    */
    ...mapActions('test', ['add', 'increment']),//变动,添加test模块
    ...mapActions('test', {//变动,添加test模块
      delayAdd2: 'delayAdd'
    })
  }
}
</script>



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UniApp是一个基于Vue.js的跨平台开发框架可以用于开发iOS、Android、H5等多个平台的应用程序。而VuexVue.js官方提供的状态管理库,用于集中管理应用程序的状态。 在UniApp中使用Vuex可以帮助我们更好地管理应用程序的状态,实现数据的共享和响应式更新。下面是使用Vuex的步骤: 1. 安装Vuex:在UniApp项目的根目录下,使用npm或者yarn安装Vuex。 ``` npm install vuex --save ``` 2. 创建store:在项目的src目录下创建一个store文件夹,并在该文件夹下创建一个index.js文件。在index.js中引入VueVuex,并创建一个新的Vuex.Store实例。 ```javascript import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ // 在这里定义你的状态和相关操作 }) export default store ``` 3. 定义状态和操作:在store文件夹下创建一个modules文件夹,并在该文件夹下创建一个module.js文件。在module.js中定义你的状态和相关操作。 ```javascript const module = { state: { count: 0 }, mutations: { increment(state) { state.count++ } }, actions: { incrementAsync({ commit }) { setTimeout(() => { commit('increment') }, 1000) } } } export default module ``` 4. 在main.js中引入store:在main.js中引入刚刚创建的store,并将其挂载到Vue实例上。 ```javascript import Vue from 'vue' import App from './App' import store from './store' Vue.config.productionTip = false App.mpType = 'app' const app = new Vue({ store, ...App }) app.$mount() ``` 现在,你就可以在组件中使用Vuex了。可以通过`this.$store.state`访问状态,通过`this.$store.commit`调用mutations中的方法,通过`this.$store.dispatch`调用actions中的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值