一、安装
NPM
npm install vuex --save
Yarn
yarn add vuex
在main.js引入使用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
创建store文件夹,里面创建一个js文件 store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex) // 必须显式地通过 Vue.use() 来安装 Vuex
export default new Vuex.Store({
state: {
addCount: 0, // 显示的数值
subCount: 1
},
mutations: {
},
actions: {
},
modules: {
}
})
二、开始使用(显示)---state
在vue中state有三种用法(显示)
第一种
<div>增加的数量1:{{$store.state.addCount}}</div>
第二种
<div>减少的数量:{{countTest}}</div>
<script>
export default {
data() {
return {
countTest: null
}
},
mounted() {
this.countTest = this.$store.state.subCount;
},
}
</script>
第三种
<div>增加的数量2:{{addCount}}</div>
<script>
import {mapState} from 'vuex'
export default {
computed: {
...mapState(['addCount'])
},
}
</script>
三、Mutation
Mutation用于变更Store中的数据
① 只能通过mutation变更Store数据,不可以直接操作Store中的数据。
② 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
mutations: {
/*
add 函数接收两个参数
state: store里面的state对象(和mutition平级的state)
data: 外界传入的值,可以随意命名,a,b,c都可以
*/
add(state,data) {
// 每点击一次,在原来的基础上加 data数值
state.addCount += data;
}
},
触发mutations的第一种方式
methods: {
handleAdd() {
// commit 的作用, 就是调用某个 mutation 函数
this.$store.commit('add',2)
}
},
触发mutations的第二种方式
export default new Vuex.Store({
state: {
addCount: 0, // 显示的数值
subCount: 1,
aTest: '我是测试1'
},
mutations: {
/*
add 函数接收两个参数
state: store里面的state对象(和mutition平级的state)
data: 外界传入的值,可以随意命名,a,b,c都可以
*/
add(state,data) {
// 每点击一次,在原来的基础上加 data数值
state.addCount += data;
},
sub(state,step) {
state.aTest = step;
}
},
})
<script>
// 从vuex 中 按需导入 mapMutations 函数
import {mapState, mapMutations} from 'vuex'
export default {
computed: {
...mapState(['addCount'])
},
// 通过导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法
methods: {
// 讲指定的mutations 函数,映射为当前组件的methods 函数
...mapMutations(['sub']),
handleAdd() {
this.$store.commit('add',2)
},
handleTihuan() {
this.sub('嘿嘿嘿!!!')
}
},
}
</script>
四、Actions
Actions 用于处理异步任务。
如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。
触发actions的第一种方式:
export default new Vuex.Store({
state: {
addCount: 0, // 显示的数值
},
mutations: {
add(state) {
state.addCount += 1;
},
},
actions: {
asyncAdd(context) {
setTimeout(()=>{
context.commit('add')
},1000)
}
},
})
-----------------
methods: {
handleAdd() {
this.$store.dispatch('asyncAdd') // store 里面的方法名是哪个就在dispatch里面写哪个方法名
},
},
触发actions异步任务时携带参数:
actions: {
asyncAdd(context,step) {
setTimeout(()=>{
context.commit('add',step)
},1000)
}
}
-----
this.$store.dispatch('asyncAdd',2)
触发actions的第二种方式:
actions: {
asyncSub(context,step) {
setTimeout(()=>{
context.commit('sub',step)
},1000)
}
},
------
import {mapState, mapMutations, mapActions} from 'vuex'
methods: {
...mapMutations(['sub']),
...mapActions(['asyncSub']),
handleSub() {
this.asyncSub(1);
},
},
------
// 或者直接在DOM元素中使用
<div>减少的数量:{{$store.state.subCount}}</div>
<!-- <el-button type="warning" @click="handleSub">减少</el-button> -->
<el-button type="warning" @click="asyncSub(2)">减少</el-button>
五、Getters
Getters用于对Store中的数据进行加工处理形成新的数据
① Getters 可以对Store 中已有的数据加工处理之后形成新的数据,类似于Vue的计算属性。
② Store 中数据发生变化,Getters 的数据也会跟着变化。
使用getters的第一种方式:
getters: {
// 这里的state 是store 里面state
showNumber: state => {
return '当前最新的数据是【'+ state.testCount +'】'
}
},
-----------
// this.$store.getters.名称
this.$store.getters.showNumber
使用getters的第二种方式:
import {mapState, mapMutations, mapActions, mapGetters} from 'vuex'
--------------
computed: {
...mapGetters(['showNumber'])
},
-----------
<div>{{showNumber}}</div>
六、modules(我这里后面更新的是vuex@4以上的)
1、先在store文件夹创建一个modules文件夹,里面新建你要见名知意的文件,我这里就使用home.js
modules.png
2.store文件夹里面的index.js文件
import {createStore} from 'vuex'
import home from './modules/home'
const store = createStore({
state() {
return {
counter: 100
}
},
mutations: {
increment(state) {
state.counter++;
},
decrement(state) {
state.counter--;
}
},
actions: {},
getters: {},
modules: {
home
}
})
export default store
3.modules文件夹里面的home.js
export const homeModule = {
/* 官方定义:默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的——这样使得多个模块能够对
同一个 action 或 mutation 作出响应。
Getter 同样也默认注册在全局命名空间,但是目前这并非出于功能上的目的(仅仅是维持现状来避免非兼容性变更)。
必须注意,不要在不同的、无命名空间的模块中定义两个相同的 getter 从而导致错误。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。
当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调 整命名
namespaced: true, // 开启命名空间 */
state(){
return {
homeCounter: 100
}
},
mutations: {
increment(state) {
state.homeCounter++;
}
},
actions: {
incrementAction(context) {
context.commit('increment')
}
},
getters: {
doubleHomeCounter(state) {
return state.homeCounter*2;
}
}
}
export default homeModule
4、在页面用使用
基本的写法:(普通写法)
<template>
<div class="container">
<div>这是测试modules的组件</div>
module的值:<h3>{{$store.state.home.homeCounter}}</h3>
module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
modules的按钮:<button @click="increment">+1</button>
modules的按钮action:<button @click="incrementAction">+1</button>
</div>
</template>
<script>
export default {
methods: {
increment() {
this.$store.commit('home/increment')
},
incrementAction() {
this.$store.dispatch('home/incrementAction')
}
},
}
</script>
辅助函数的写法
第一种写法:(辅助函数写法)
<template>
<div class="container">
<div>这是测试module辅助函数的组件</div>
module的值:<h3>{{homeCounter}}</h3>
module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
modules的按钮:<button @click="increment">+1</button>
modules的按钮action:<button @click="incrementAction">+1</button>
</div>
</template>
<script>
import {mapState, mapMutations, mapGetters,mapActions} from 'vuex'
export default {
name: '',
components: {
},
data() {
return {
}
},
computed: {
// 写法一
...mapState({
homeCounter: state => state.home.homeCounter
}),
...mapGetters({
doubleHomeCounter: "home/doubleHomeCounter"
})
},
mounted() {
},
methods: {
// 写法一
...mapMutations({
increment: "home/increment"
}),
...mapActions({
incrementAction: "home/incrementAction"
})
},
}
</script>
第二种写法:(辅助函数写法)
<template>
<div class="container">
<div>这是测试module辅助函数的组件</div>
module的值:<h3>{{homeCounter}}</h3>
module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
modules的按钮:<button @click="increment">+1</button>
modules的按钮action:<button @click="incrementAction">+1</button>
</div>
</template>
<script>
import {mapState, mapMutations, mapGetters,mapActions} from 'vuex'
export default {
name: '',
computed: {
// 写法二
...mapState('home',['homeCounter']),
...mapGetters('home', ['doubleHomeCounter'])
},
methods: {
// 写法二
...mapMutations('home', ['increment']),
...mapActions('home', ['incrementAction']),
},
}
</script>
第三种写法:(辅助函数写法)
<template>
<div class="container">
<div>这是测试module辅助函数的组件</div>
module的值:<h3>{{homeCounter}}</h3>
module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
modules的按钮:<button @click="increment">+1</button>
modules的按钮action:<button @click="incrementAction">+1</button>
</div>
</template>
<script>
// createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:
import { createNamespacedHelpers } from 'vuex'
// 解构 createNamespacedHelpers("home") 里面的home 是你文件的名字,我这里是创建了home.js
const {mapState, mapMutations, mapGetters,mapActions} = createNamespacedHelpers("home")
export default {
name: '',
computed: {
// 写法三
...mapState(['homeCounter']),
...mapGetters(['doubleHomeCounter'])
},
mounted() {
},
methods: {
// 写法三
...mapMutations(['increment']),
...mapActions(['incrementAction']),
},
}
</script>