安装:npm view vuex versions
如果项目还没有创建好,那么在用脚手架创建项目的时候记得选上vuex,这样脚手架会去寻找最兼容的版本来安装,不用我们担心,如果迫不得已需要手动安装和配置,那么就需要确定使用的版本,vue 2我推荐使用vuex的3.x的版本,但是我们不知道vuex 3.x的版本中的最新版是什么,可以用下面的命令来查看vuex在npm仓库中的所有版本
npm view vuex versions
# [
# '0.1.0', '0.2.0', '0.3.0', '0.4.0',
# '0.4.1', '0.4.2', '0.5.0', '0.5.1',
# '0.6.1', '0.6.2', '0.6.3', '0.7.0',
# '0.7.1', '0.8.0', '0.8.1', '0.8.2',
# '1.0.0-rc', '1.0.0-rc.2', '1.0.0', '1.0.1',
# '2.0.0-rc.1', '2.0.0-rc.3', '2.0.0-rc.4', '2.0.0-rc.5',
# '2.0.0-rc.6', '2.0.0', '2.1.0', '2.1.1',
# '2.1.2', '2.1.3', '2.2.0', '2.2.1',
# '2.3.0', '2.3.1', '2.4.0', '2.4.1',
# '2.5.0', '3.0.0', '3.0.1', '3.1.0',
# '3.1.1', '3.1.2', '3.1.3', '3.2.0',
# '3.3.0', '3.4.0', '3.5.0', '3.5.1',
# '3.6.0', '3.6.1', '3.6.2', '4.0.0-alpha.1',
# '4.0.0-beta.1', '4.0.0-beta.2', '4.0.0-beta.3', '4.0.0-beta.4',
# '4.0.0-rc.1', '4.0.0-rc.2', '4.0.0', '4.0.1',
# '4.0.2'
# ]
然后选择一个3开头的最新的那个就行了,比如上面的 3.6.2,那么可以通过下面命令来下载该版本:
npm install vuex@3.6.2 --save
vuex 的简单使用示例
按照vue脚手架创建项目勾选vuex时帮我们做的配置来看,简单的vuex这样配置:
/// src/store/index.js
/*
首先引入vue和vuex,然后通过Vue.use(Vuex)来注册vuex,
这应该会让vue初始化一些vuex需要的环境,细节我们不必在意,
除非你是框架的开发者。
*/
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
/*
然后我们创建一个store实例,顾名思义,这是一个仓库,
关于vuex使用的api我们基本是通过这个实例去获取和操作,
创建store实例的时候,我们需要传递一个配置对象
该配置对象拥有state, getters,mutations,actions和modules
五个属性,这是vuex的五个核心概念。
*/
export default new Vuex.Store({
/*
state,翻译过来就是状态的意思,顾名思义,与状态关联的数据都会保存在这里,
官方说这个state和vue中的data配置项类似,必须是纯粹的对象,这里的纯粹我
们可以理解为 其只包含属性,不包含方法,甚至getter和setter属性也不推荐。
除此之外,其他类型的数据我们都可以存储,比如数字、字符串、布尔值、对象和
数组等。
*/
state: {
},
/*
getters,这是一个类似vue中computed配置项的东西,通过getters能够通过对多个状态
进行处理,然后派生出来一个新的状态,和vue中computed属性一样,getters中的派生
状态也是响应性的。getters是在有多个组件都用到相同的派生状态时使用的,这样就
不用在每个组件中都去写一个计算属性来获取该状态了。
与vue的computed属性一样,getters是通过既有的状态计算得出的,不需要我们手动去修改其状态。
*/
getters: {
},
/*
mutations,有改变之意,官方说,更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,
这是什么意思呢,我们知道,因为我们保存状态数据使用一个对象state去保存的,我们获取state
可以类似store.state.**的方式来读取,按理说我们通过store.state.** = **这种直接修改的
方式来修改状态,事实上好像也是可以的,但是官方说不推荐,而是尽量使用提交mutation的方式
来修改状态,可能我们不知道为啥,但是官方都这么说,咱就这么用,如果真的不听官方的话,
干脆不用算了,我不是杠,万一不按照官方的来,出bug了咋办?
值得注意的是,尽量不要在mutation里面进行异步操作,尤其是需要在异步操作结果返回时修改状态
的时候,不用我多说了吧,这也是官方说的,至于为什么,就需要去挖源码看看咯。
*/
mutations: {
},
/*
actions,官方大大说action 类似于 mutation,不同的地方就是,mutation里面不推荐包含任何
异步操作,而action里面可以包含任意异步操作。并且action里面提交的是mutation来改变状态。
*/
actions: {
},
/*
modules,模块,没错,vuex也是可以分模块进行状态管理的,配置在modules中的每一个module,
其实都是一个对象,每个module对象都是类似于store的对象,也就是都可以有自己的state,getters,
mutations和actions,除此之外,还可以添加命名空间的属性 namespaced: Boolean,添加了命名空间,
访问的时候就要用store.state.moduleName.**的方式。
*/
modules: {
}
})
导出的这个store需要在项目入口中,新建vue根实例的时候传入配置对象:
///main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
new Vue({
store,
render: h => h(App)
}).mount('#app')
项目中实际运用:
1,在store中定义数据,在组件中直接使用:
目录: store/index.js
export default new Vuex.store({
// state相当于组件中的data 专门用来存放全局的数据
state:{
num:0
},
getters:{},
mutations:{},
actions:{},
modules:{}
})
目录:Home.vue
<template>
<div>这是home:{{$store.state.num}}</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
或者写为:
<template>
<div>
这是about:{{num}}
</div>
</template>
<script>
export default {
computed:{
num(){
return this.$store.state.num
}
}
}
</script>
<style>
</style>
2 getter 讲组件中统一使用的computed 都放到getter中使用
目录:/store/index.js
export default new Vuex.store({
// state相当于组件中的data 专门用来存放全局的数据
state:{
num:0
},
getters:{
// getters相当于是computed getters是全局的 而computed是组件内部的
getNum(state){
return state.num
}
},
mutations:{},
actions:{},
modules:{}
})
目录:home.vue
<template>
<div>这是home:{{$store.getters.getnum}}</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
3 mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
目录:/store/index.js
export default new Vuex.store({
// state相当于组件中的data 专门用来存放全局的数据
state: {
num: 0
},
// getters相当于是conputed getters是全局的 而conputed是组件内部的
getters: {
getNum(state) {
return state.num
}
},
//相当于组件中的methods方法 但是他不能使用异步方法(定时器 axios)
// payload 是一个形参 如果组件在commit时 有传参数时就存在 如果没有传过来就是undefined
mutations: {
increase(state, payload) {
// 让num+1
state.num += payload ? payload : 1
}
},
actions: {},
modules: {}
})
目录:btn.vue
<template>
<div>
<button @click="addfn">点击我加加</button>
</div>
</template>
<script>
export default {
methods:{
addfn(){
this.$store.commit("increase",2)
}
}
}
</script>
<style>
</style>
4,Action
// actions专门用来处理异步 实际修改状态值的 还是mutations
目录:store/index.js
export default new Vuex.store({
// state相当于组件中的data 专门用来存放全局的数据
state: {
num: 0
},
// getters相当于是conputed getters是全局的 而conputed是组件内部的
getters: {
getNum(state) {
return state.num
}
},
//相当于组件中的methods方法 但是他不能使用异步方法(定时器 axios)
// payload 是一个形参 如果组件在commit时 有传参数时就存在 如果没有传过来就是undefined
mutations: {
increase(state, payload) {
// 让num+1
state.num += payload ? payload : 1
},
decrease(state) {
state.num--
}
},
// actions专门用来处理异步 实际修改状态值的 还是mutations
actions: {
// 点击按钮后放慢一秒再减
decreaseAsync(contest) {
contest.commit('decrease')
}
},
modules: {}
})
目录:btn.vue
<template>
<div>
<button @click="addfn">点击我加加</button>
<button @click="decrease">点击我减减</button>
</div>
</template>
<script>
export default {
methods:{
addfn(){
this.$store.commit("increase",2)
// this.$store.dispatch('decrease')
},
decrease(){
this.$store.dispatch('decreaseAsync')
}
}
}
</script>
<style>
</style>
其他的书写方式:
5 map辅助函数
...mapState 和...mapGetters都是写在computed组件里面
<template>
<div>这是about:组件{{ num }}</div>
<div>这是home:{{getnum}}</div>
</template>
<script>
import { mapState, mapGetters } from "vuex";
export default {
computed: {
...mapState("num"),
...mapGetters("getnum"),
// num(){
// return this.$store.state.num
// }
},
};
</script>
<style>
</style>
mapMutations和mapActions 在组件中都是写在methods中:
template>
<div>
<!-- <button @click="addfn">点击我加加</button>
<button @click="decrease">点击我加加</button> -->
<button @click="addfn()">点击我加加</button>
<button @click="decrease()">点击我延迟减一</button>
</div>
</template>
<script>
import {mapMutations,mapActions} from 'vuex'
export default {
methods:{
...mapMutations(['increase']),
...mapActions(["decreaseAsync"]),
addfn(){
// this.$store.commit("increase",2)
// this.$store.dispatch('decrease')
this.increase()
},
decrease(){
this.decreaseAsync()
// this.$store.dispatch('decreaseAsync')
}
}
}
</script>
<style>
</style>
6 拆分写法
stroe中所有的属性 都可以拆分成js文件 引入来写。