Vue学习笔记(九)--- Vuex

一、Vuex 概述

​ Vuex 是实现组件全局数据管理的一种机制,可以很方便的实现组件之间的数据共享。我们之前学习的组件之间的数据共享方式,如父子组件传值、EventBus 等,都只适用于小范围的数据共享。而 Vuex 可以实现整个项目范围的数据共享。

​ 使用 Vuex 统一管理全局数据的优点:① 能够集中管理共享的数据,易于开发和后期维护。 ② 能够高效的实现组件之间的数据共享,提高开发效率。 ③ 存储在 vuex 中的数据是响应式的,能够实时保持数据与页面的同步。

在这里插入图片描述

二、Vuex 的安装

1、打开项目终端,输入 npm install vuex --D,下载vuex相关包。
2、在生成的 store/index.js 中,导入 vuex 包,并将其注入到 Vue 中。
3、创建 vuex 的 store 实例对象。
// 导入 vue
import Vue from 'vue'
// 导入 vuex
import Vuex from 'vuex'
// 将 vuex 注入到Vue中
Vue.use(Vuex)
// 创建实例对象
export default new Vuex.Store({
  // state 中存放的就是全局共享的数据
  state: {
    count: 0
  }
})
4、在项目的 main.js 中,将 store 实例对象挂载到 vue 实例上。
import Vue from 'vue'
import App from './App.vue'
// 导入对应实例对象
import store from './store'

new Vue({
  // 将创建的 store对象,挂载到 Vue实例中
  // 此时项目中的所有组件都可从该对象中获取数据
  // store 是简写,全写为:store: store
  store,
  render: h => h(App)
}).$mount('#app')

三、Vuex的核心属性和使用方法

1、State

​ state 提供唯一的公共数据源,所有共享的数据都要统一放到 state中进行存储,state 中的数据不可直接进行修改。

// 创建实例对象
const store = new Vuex.Store({
    // 存储所有共享数据
    state: {
        count: 1
    }
})

组件中访问 state中存储的数据的两种方式:

① this.$store.state.全局数据名称
<!-- 在html中使用 -->
<h1>当前最新的count值为:{{$store.state.count}}</h1> 
<!-- 在js中使用 -->
<script>
	const num = this.$store.state.count
</script>
② 先按需导入vuex中的 mapState 函数,再通过该函数将需要的全局数据映射为当前组件的计算属性。
// 1. 从 vuex 中按需导入 mapState 函数
import { mapState } from 'vuex'

export default {
  computed: {
    // 2.通过 mapState 函数将需要的全局数据,映射为当前组件的计算属性使用
    // 以数组的形式,可映射多个全局数据
    ...mapState(['count'])
  }
}
2、Mutation

​ state 中的数据不可直接进行修改,只能通过 mutation 来变更 state 中的数据。虽然这会使操作变得繁琐,但是可以集中监控所有数据的变化。

// 创建实例对象
const store = new Vuex.Store({
    // 存储所有共享数据
    state: {
        count: 1
    },
    // 定义 mutation 
    mutations: {
     	// 修改 state 中的数据
        add(state) {
      		state.count++
   	 	},
        // 可以传递参数
        //第一个形参永远都是state也就是$state对象
      	//第二个形参是调用时传递的参数
        addN(state, step) {
            // 修改 state 中的数据
     		state.count += step
    	}
    }
})

组件中触发 mutation的两种方式:

① this.$store.commit(‘mutation函数名’[,参数])
method: {
    handle() {
        // 通过 commit 函数来触发 mutation 中的函数
        // 可以传递参数
        this.$store.commit('addN',3)
    }
}
② 先按需导入vuex中的 mapMutations 函数,再通过该函数将需要的 mutation 函数映射为当前组件的 methods 方法。
// 1. 从 vuex 中按需导入 mapMutations 函数
import { mapMutations } from 'vuex'

export default {
  methods: {
    // 2.通过 mapMutations 函数将需要的 mutation 函数,映射为当前组件的 methods 函数使用
    // 以数组的形式 可映射多个 mutation 函数
    ...mapMutations(['add','addN'])
  }
}
3、Action

​ Action 用来处理异步任务,在 mutation 中不能编写异步代码,会导致vue调试器的显示出错。但是Action 不能直接操作 state 中的数据,需要通过触发 mutation 来间接操作数据。

// 创建实例对象
const store = new Vuex.Store({
    // 存储所有共享数据
    state: {
        count: 1
    },
    // 定义 mutation 
    mutations: {
        // 可以传递参数
        addN(state, step) {
            // 修改 state 中的数据
     		state.count += step
    	}
    },
    // 定义 Action
    actions: {
        addNASync(context,step) {
            // 异步操作
            setTimeout(() => {
                // 通过 commit 触发 mutation 来操作 state 中的数据
                context.commit('addN',step)
            })
        }
    }
})

组件中触发 Action 的两种方式:

① this.$storw.dispatch(‘action函数名’)
method: {
    handle() {
        // 通过 dispatch 函数来触发 action
        // 可以传递参数
        this.$store.dispatch('addNASync'5)
    }
}
② 先按需导入vuex中的 mapActions 函数,再通过该函数将需要的 action 函数,映射为当前组件的 methods 方法。
// 1. 从 vuex 中按需导入 mapActions 函数
import { mapActions } from 'vuex'

export default {
  methods: {
    // 2.通过 mapActions 函数将需要的 action 函数,映射为当前组件的 methods 方法使用
    // 以数组的形式 可映射多个 action 函数
    ...mapActions(['addNASync'])
  }
}
4、Getter

​ Getter 用来对 state 中的数据进行加工处理并返回新的数据,类似于组件的计算属性。它不是对原有数据的修改,而是对其进行加工,并返回一个新的数据,state中的原数据不变。但是当 state 中的原数据发生改变时,Getter 的数据也会随之改变。

// 创建实例对象
const store = new Vuex.Store({
    // 存储所有共享数据
    state: {
        count: 1
    },
    getters: {
        // 参数 state 便是上面的 state
    	showNum(state) {
      		return '当前最新的数量是【' + state.count + '】'
    	}
  	}
})

组件中触发 Getter 的两种方式:

① this.$store.getters.getter函数名
<!-- 在html中使用 -->
<h1>{{$store.getters.showNum}}</h1> 
<!-- 在js中使用 -->
<script>
	const num = this.$store.getters.showNum
</script>
② 先按需导入vuex中的 mapGetters 函数,再通过该函数将需要的 getter 映射为当前数组的 computed。
// 1. 从 vuex 中按需导入 mapGetters  函数
import { mapGetters  } from 'vuex'

export default {
  computed: {
    // 2.通过 mapGetters  函数将需要的 getter 映射为当前组件的 computed
    // 以数组的形式 可映射多个 getter 函数
    ...mapGetters(['showNum'])
  }
}

四、综合案例

1、store/index.js 文件
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  },
  // 只有 mutations 中定义的函数,才有权利修改 state 中的数据
  mutations: {
    add(state) {
      // 不要在 mutations 函数中,执行异步操作
      // setTimeout(() => {
      //   state.count++
      // }, 1000)
      state.count++
    },
    addN(state, step) {
      state.count += step
    },
    sub(state) {
      state.count--
    },
    subN(state, step) {
      state.count -= step
    }
  },
  actions: {
    addAsync(context) {
      setTimeout(() => {
        // 在 actions 中,不能直接修改 state 中的数据;
        // 必须通过 context.commit() 触发某个 mutation 才行
        context.commit('add')
      }, 1000)
    },
    addNAsync(context, step) {
      setTimeout(() => {
        context.commit('addN', step)
      }, 1000)
    },
    subAsync(context) {
      setTimeout(() => {
        context.commit('sub')
      }, 1000)
    },
    subNAsync(context, step) {
      setTimeout(() => {
        context.commit('subN', step)
      }, 1000)
    }
  },
  getters: {
    showNum(state) {
      return '当前最新的数量是【' + state.count + '】'
    }
  }
})

2、Subtraction.Vue 组件
<template>
  <div>
    <!-- <h3>当前最新的count值为:{{count}}</h3> -->
    <h3>{{showNum}}</h3>
    <button @click="btnHandler1">-1</button>
    <button @click="subN(3)">-N</button>
    <button @click="subAsync">-1 Async</button>
    <button @click="subNAsync(5)">-N Async</button>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'

export default {
  data() {
    return {}
  },
  computed: {
    ...mapState(['count']),
    ...mapGetters(['showNum'])
  },
  methods: {
    ...mapMutations(['sub', 'subN']),
    ...mapActions(['subAsync', 'subNAsync']),
    btnHandler1() {
      this.sub()
    }
  }
}
</script>
3、Addition.vue 组件
<template>
  <div>
    <!-- <h3>当前最新的count值为:{{$store.state.count}}</h3> -->
    <h3>{{$store.getters.showNum}}</h3>
    <button @click="btnHandler1">+1</button>
    <button @click="btnHandler2">+N</button>
    <button @click="btnHandler3">+1 Async</button>
    <button @click="btnHandler4">+N Async</button>
  </div>
</template>

<script>
export default {
  data() {
    return {}
  },
  methods: {
    btnHandler1() {
      this.$store.commit('add')
    },
    btnHandler2() {
      // commit 的作用,就是调用 某个 mutation 函数
      this.$store.commit('addN', 3)
    },
    // 异步地让 count 自增 +1
    btnHandler3() {
      // 这里的 dispatch 函数,专门用来触发 action
      this.$store.dispatch('addAsync')
    },
    btnHandler4() {
      this.$store.dispatch('addNAsync', 5)
    }
  }
}
</script>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的小朱同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值