准备
Vuex安装与引入
错误解决方法:yarn : 无法加载文件 D:\nodejs\yarn.ps1,因为在此系统上禁止运行脚本。
附加:打开了命令行之后,输入set-ExecutionPolicy RemoteSigned,并且把权限改权限为A,然后通过 get-ExecutionPolicy 查看当前的状态
src/store/idnex.js
// 用来做状态管理
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// state相当于组件中的data,专门用来存放全局的数据
state: {
num:0
},
getters:{},
mutations:{},
actions:{},
modules:{}
})
state
在store中定义数据,在组件中直接使用
目录:store/index.js
export default new Vuex.Store({
// state相当于组件中的data,专门用来存放全局的数据
state: {
num:0
},
getters:{},
mutations:{},
actions:{},
modules:{}
})
目录:Home.vue
<template>
<div class="home">
<h2>Home页面的数字:{{$store.state.num}}</h2>
</div>
</template>
<script>
export default {
}
</script>
或者写为:
<template>
<div class="about">
<h2>About页面的数字:{{num}}</h2>
</div>
</template>
<script>
export default {
computed: {
num() {
return this.$store.state.num
}
}
}
</script>
getters
将组件中统一使用的computed都放到getters里面来操作
目录:store/index.js
// 用来做状态管理
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// state相当于组件中的data,专门用来存放全局的数据
state: {
num:0
},
// getters相当于组件当中的computed,getters是全局的,computed是组件内部的
getters:{
getNum(state) {
return state.num
}
},
mutations:{},
actions:{},
modules:{}
})
目录:Home.vue
<template>
<div class="home">
<h2>Home页面的数字:{{$store.getters.getNum}}</h2>
</div>
</template>
<script>
export default {
}
</script>
mutations
更改Vuex的store中的状态的唯一方法是提交mutation
目录:store/index.js
// 用来做状态管理
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// state相当于组件中的data,专门用来存放全局的数据
state: {
num:0
},
// getters相当于组件当中的computed,getters是全局的,computed是组件内部的
getters:{
getNum(state) {
return state.num
}
},
// mutations相当于组件中的methods,但是它不能使用异步方法(定时器、axios)
mutations:{
// payload是一个形参 如果组件在commit时,有传这个参数,就存在
add(state, payload) {
state.num += payload ? payload : 1;
}
},
actions:{},
modules:{}
})
Btn.vue
<template>
<div>
<button @click="addFn">点击加1</button>
</div>
</template>
<script>
export default {
methods: {
addFn() {
// 调用store中的mutations里的add方法
// 传参使用payload
this.$store.commit('add', 2)
}
}
}
</script>
<style>
</style>
actions
actions是store中专门用来处理异步的,实际修改状态值的还是mutations
// 用来做状态管理
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// state相当于组件中的data,专门用来存放全局的数据
state: {
num:0
},
// getters相当于组件当中的computed,getters是全局的,computed是组件内部的
getters:{
getNum(state) {
return state.num
}
},
// mutations相当于组件中的methods,但是它不能使用异步方法(定时器、axios)
mutations:{
// payload是一个形参 如果组件在commit时,有传这个参数,就存在
add(state, payload) {
state.num += payload ? payload : 1;
},
sub(state) {
state.num--;
}
},
// actions专门用来处理异步,实际修改状态值的,依然是mutations
actions:{
// 点击减1 1秒后执行
subAsync(context) {
setTimeout(() => {
context.commit('sub')
},1000)
}
},
modules:{}
})
Btn.vue
<template>
<div>
<button @click="addFn">点击加1</button>
<button @click="reduceFn">点击减1</button>
</div>
</template>
<script>
export default {
methods: {
addFn() {
// 调用store中的mutations里的add方法
// 传参使用payload
this.$store.commit('add', 2)
},
reduceFn(){
this.$store.dispatch('subAsync')
}
}
}
</script>
<style>
</style>
辅助函数map*
mapState和mapGetters在组件中都是写在computed中
Home.vue
<template>
<div class="home">
<h2>Home页面的数字:{{$store.getters.getNum}}</h2>
</div>
</template>
<script>
// 映射
import {mapState} from 'vuex'
export default {
computed: {
...mapState(['num'])
}
}
</script>
About.vue
<template>
<div class="about">
<h2>About页面的数字:{{$store.getters.getNum }}</h2>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
computed: {
...mapGetters(['getNum'])
}
}
</script>
mapMutations和mapActions在组件中都是写在methods中
<template>
<div>
<button @click="add(2)">点击加1</button>
<button @click="subAsync()">点击减1</button>
</div>
</template>
<script>
import { mapMutations, mapActions} from 'vuex'
export default {
methods: {
...mapMutations(['add']),
...mapActions(['subAsync'])
}
}
</script>
拆分写法
store中的所有属性,都可以拆分成单独的js文件来写
store一般不拆出去 在index.js中
index.js
// 用来做状态管理
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import getters from './getters'
import mutations from './mutations'
import actions from './actions'
Vue.use(Vuex)
export default new Vuex.Store({
// state相当于组件中的data,专门用来存放全局的数据
state,
// getters相当于组件当中的computed,getters是全局的,computed是组件内部的
getters,
// mutations相当于组件中的methods,但是它不能使用异步方法(定时器、axios)
mutations,
// actions专门用来处理异步,实际修改状态值的,依然是mutations
actions,
modules:{}
})
state.js
export default {
num:0
}
getters.js
export default {
getNum(state) {
return state.num
}
}
mutations.js
export default {
// payload是一个形参 如果组件在commit时,有传这个参数,就存在
add(state, payload) {
state.num += payload ? payload : 1;
},
sub(state) {
state.num--;
}
}
actions.js
export default {
// 点击减1 1秒后执行
subAsync(context) {
setTimeout(() => {
context.commit('sub')
},1000)
}
}
modules
store可以认为是一个主模块,它下边可以分解为很多子模块,子模块都可以单独分出来,写完再导入到主模块中。
下面以users子模块举例
所有的方法和属性,该怎么写就怎么写,但是users的index.js中,需要写入namespacee:true
命名空间
然后引入到store的index.js的modules中
在组件中获取的方法:
$store.state.users.nickNames
在组件中触发mutations的方法:
methods: {
...mapMutations({
'changeNickName': 'user/changeNickName'
})
}
注意:这里我按上方写法,竟然会报错,直接写成数组,里面写方法名字,反而不会报错,正常运行了
MUTATIONS_TYPE
将mutations中所有的方法归纳起来。
目录:mutations_type.js
export const MUTATIONS_TYPE = {
ADD: 'add',
SUB : 'SUB'
}
export default {
// payload是一个形参 如果组件在commit时,有传这个参数,就存在
[MUTATIONS_TYPE.ADD](state, payload) {
state.num += payload ? payload : 1;
},
[MUTATIONS_TYPE.SUB](state) {
state.num--;
}
}
目录:store/index.js
// import mutations from './mutations'
import mutations from './mutations_type'
组件中
<template>
<div class="about">
<h2>About页面的数字:{{$store.getters.getNum }}</h2>
<button @click="add()">About的按钮,点击加1</button>
</div>
</template>
<script>
import {mapGetters,mapMutations} from 'vuex'
import {MUTATIONS_TYPE} from '@/store/mutations_type'
export default {
computed: {
...mapGetters(['getNum'])
},
methods: {
// ...mapMutations([MUTATIONS_TYPE.ADD])
add() {
this.$store.commit(MUTATIONS_TYPE.ADD)
}
}
}
</script>