1.安装Vue 依赖包
npm install vuex --save
2.导入 vuex 包
创建 store.js
文件 和 main.js
平级
import Vue from 'vue'
import Vuex from 'vuex' //导入vuex
Vue.use(Vuex) //把Vuex安装到项目里面
export default new Vuex.Store({
//state中存放的就是全局共享的数据
state:{
},
mutations:{
},
actions:{
}
})
3.创建store对象
这一步和第二步里面内容重复可以不添加,看自己需求
const store = new Vuex.Store({
//state中存放的就是全局共享的数据
state:{
state:{ count:0}
},
})
4.将 store 对象挂载到vue实例中
打开 main.js
引入store.js
import store from './store'
挂载到vue实例中
el: '#app',
render:h => h(App),
router,
//将创建的共享数据对象,挂载在vue实例中
//所有的组件,就可以直接从store中获取全局的数据了
store
})
Vuex 应用
state
作用:获取数据
组件访问state中数据的第一种方式 :
this.$store.state.全局数据名称
组件访问state中数据的第二种方式 :
从vuex中按需导入mapState 函数
import { mapState } from 'vuex'
通过刚才导入的mapState 函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性
computed: {
...mapState(['count'])//count 是store中全局共享数据名称 获取store中的数据
}
mutations
**作用:**修改全局state中的数据
只能 通过 Mutation
修改 state
中的数据,可以集中监控所有数据的变化。不可以直接操作 store
中的数据
**不传参数:**在 mutations
中定义一个 add(state)
函数。第一个参数永远都是一个 state 代表全局对象,直接state.属性就可以调用全局共享数据的属性,
传参数: addN(state,step) step 外界传过来的参数
触发mutation 的第一种方式
不传参数:this.$store.commit('add')
add 是Mutation中定义的函数名
传参数 : this.$store.commit('addN',参数)
触发mutation 的第二种方式
从 vuex
中按需导入 mapMutations
函数
import { mapMutations } from 'vuex'
通过刚才导入的 mapMutations
函数,将需要的 mutations
,映射为当前组件的 methods
方法
methods: {
...mapMutations(['sub', 'subN']), //吧全局mutations里面的sub函数映射为当前组件的methods
}
this.subAsync();//可以直接调用
注意:在 mutations
中不要执行异步操作
actions
**作用:**用于处理异步任务
如果通过异步操作变更数据,必须通过 action
,而不能使用 Mutation
,但是在 Action
还是要通过触发 Mutation
的方式间接变更数据
在 action
中定义一个 addAsync(context)
函数 context
相当于new出来的 store
的实体对象
修改state中的数据必须通过 mutations
触发Actions 的第一种方式
this.$store.dispatch('addAsync') //addAsync adction中的函数 dispatch函数 专门用来触发 action
触发Actions 的第二种方式
从vuex中按需导入 mapActions
函数
import { mapActions } from 'vuex'
通过刚才导入的 mapActions
函数,将需要的 actions
函数 ,映射为当前组件的methods方法
methods: {
...mapActions(['subAsync', 'subAsyncN'])
}
getters
作用: 包装作用,不会修改数据
在getters中定义一个函数
//定义函数
showNum(state) {
return '当前最新数据是[' + state.count + ']'
}
使用getters第一种方式
this.$store.getters.名称
this.$store.getters.showNum
使用getters第二种方式
从vuex中按需导入 mapGetters
函数
//组件访问state中数据的第二种方式 先导入
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex';
通过刚才导入的mapGetters函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性
computed: {
...mapGetters(['showNum']),
}
Demo 计算小例子
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// new Vue({
// el: '#app',
// router,
// components: { App },
// template: '<App/>'
// })
new Vue({
el: '#app',
render:h => h(App),
router,
//将创建的共享数据对象,挂载在vue实例中
//所有的组件,就可以直接从store中获取全局的数据了
store
})
store.js
import { subset } from 'semver'
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//state中存放的就是全局共享的数据
state: {
//全局count值為0
count: 0
},
mutations: {
//定义一个add函数 第一个参数永远都是一个state 代表全局对象
//加1
add(state) {
state.count++
},
//加N
addN(state, step) {
state.count += step
},
//减1
sub(state) {
state.count--
},
//减N
subN(state, step) {
state.count -= step
}
},
actions: {
//异步操作 context相当于new 出来的store的实体对象
addAsync(context) {
setTimeout(() => {
//修改state中的数据必须通过mutations
context.commit('add')
}, 2000)
},
//等会2秒异步加N
addAsyncN(context, step) {
setTimeout(() => {
//修改state中的数据必须通过mutations
context.commit('addN', step)
}, 2000)
},
//等待2秒异步减1
subAsync(context) {
setTimeout(() => {
//修改state中的数据必须通过mutations
context.commit('sub')
}, 2000)
},
//等待2秒异步减N
subAsyncN(context, step) {
setTimeout(() => {
//修改state中的数据必须通过mutations
context.commit('subN', step)
}, 2000)
}
},
getters: {
//定义函数
showNum(state) {
return '当前最新数据是[' + state.count + ']'
}
}
})
addition.vue 加法组件
<template>
<div>
<!-- 加法组件 -->
<!-- 组件访问state中数据的第一种方式 this.$store.state.全局数据名称 -->
<h3>当前最新的count值为:{{ $store.state.count }}</h3>
<h3>getter包装的:{{ $store.getters.showNum }}</h3>
<button @click="btnadd">+1</button>
<button @click="btnadd2">+3</button>
<button @click="btnadd3">等待2秒异步+1</button>
<button @click="btnadd4">等待2秒异步+10</button>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
//调用mutations中提供的一个函数
btnadd() {
this.$store.commit('add');
},
btnadd2() {
this.$store.commit('addN', 3);
},
btnadd3() {
//dispatch函数 专门用来触发 action
this.$store.dispatch('addAsync');
},
btnadd4() {
//dispatch函数 专门用来触发 action
this.$store.dispatch('addAsyncN', 10);
},
},
};
</script>
subtraction.vue 减法组件
<template>
<div>
<!-- 减法组件 -->
<h3>当前最新的count值为:{{ count }}</h3>
<h3>getter包装的:{{ showNum }}</h3>
<button @click="sub">-1</button>
<button @click="subN(3)">-3</button>
<button @click="btnSub3">等待2秒异步-1</button>
<button @click="btnSub4">等待2秒异步-10</button>
</div>
</template>
<script>
//组件访问state中数据的第二种方式 先导入
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex';
export default {
data() {
return {};
},
computed: {
//...展开运算符 吧全局里面的那些数据映射为当前组件的计算属性
//count store中全局共享数据名称 获取store中的数据
...mapState(['count']),
...mapGetters(['showNum']),
},
methods: {
...mapMutations(['sub', 'subN']), //吧全局mutations里面的sub函数映射为当前组件的methods
...mapActions(['subAsync', 'subAsyncN']),
// btnSub(){
// this.sub();//或者直接加到@click上
// },
// btnSub2(){
// this.subN(3);//或者直接加到@click上
// },
btnSub3() {
this.subAsync(); //或者直接加到@click上
},
btnSub4() {
this.subAsyncN(10); //或者直接加到@click上
},
},
};
</script>
App.vue 跟组件
<template>
<div>
<my-add></my-add>
<p>-------------------------------------------</p>
<my-sub></my-sub>
</div>
</template>
<script>
//导入组件
import addition from './components/addition.vue';
import subtraction from './components/subtraction.vue';
export default {
name: 'App',
//注册组件
components: {
'my-add': addition,
'my-sub': subtraction,
}
}
</script>
<style>
</style>
效果图如下: