本来是不打算学这个的,但是用到了,没办法只好学一下。当然只是学习一些基本的用法,想要在大项目中用好还是很难的
可以先看一下官方文档
vuex官方文档
看完官方文档可以再看一下这篇文章,我个人感觉写的很不错
点这里,知乎上的一篇文章
接下来进入正题(最好先看完上面的)
vuex的五个属性
- state 状态,相当于vue中的data属性,就是用来放数据的
- getters 在state的基础上进行延申,相当于vue中的computed。这里说一下getters不会修改state中的数据
- mutations 和 actions 这两个是来修改state的,相当于vue中的methods
- modules 模块,所有的东西不可能放在一块,通过模块可以将数据进行分类
实例
创建一个最简单的vue项目,只需要vue和vuex即可,项目目录如下
1、在src下创建store目录,store目录下创建modules目录和index.js
2、在modules目录下创建moduleA.js
moduleA.js
//state
let state = {
isShow: true, //是否显示
name: 'Tom'
}
//getters
let getters = {
//这里说下我见过的三种形式,以name属性为例
//第一种形式
getName1(state) {
return state.name
},
//第二种形式
getName2(state) {
return () => state.name
},
//上面的是箭头函数的形式
// getName2(state) {
// return function () {
// return state.name
// }
// }
//第三种
getName3(state, param) {
return param => {
return param + state.name
}
}
}
//mutations,以isShow属性为例
let mutations = {
changeShow(state) {
state.isShow = !state.isShow
},
changeName(state, data) {
state.name = data
}
}
//ctions
let actions = {
//这里有两种写法,本质上一样
//写法1,无参
asChangeShow(context) {
context.commit('changeShow')
},
//写法2,无参
// asChangeShow({ commit }) {
// commit('changeShow')
// }
//有参
asChangeName({ commit }, data) {
commit('changeName', data)
}
}
//导出模块
export default {
namespaced: true,//是否开启模块
//键和值相同时可以简写
state,
getters,
mutations,
actions
}
注:
1、getters的第一种和第二种用法都是将值给返回,至于为啥有第二种写法我也不太清楚。这里说一下第三种写法,当你要给getters传参时,返回值必须是一个函数
2、mutations和actions,上面也说了这两个相当于methods,但为啥有两个?因为mutations是同步的,当你碰到异步操作时就需要使用actions,但是actions不能直接操作state,要借助mutations来操作state
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'
Vue.use(Vuex)
export default new Vuex.Store({
store: {},
getters: {},
mutations: {},
actions: {},
modules: {
moduleA
}
})
main.js
import Vue from 'vue'
import App from './App.vue'
import store from '@/store/index'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App),
}).$mount('#app')
这里将store挂载到根实例中,这样做使得子实例直接通过this.$store
调用,而不用单独导入。如果单独导入的话,使用store
调用,与导入其它对象相同
App.vue
<template>
<div>
<h1>直接调用state</h1>
<p>我是通过计算属性直接调用的state:{{ getName }}</p>
<p>我是直接调用的state:{{ $store.state.moduleA.name }}</p>
<h1>通过getters调用state</h1>
<p>
直接调用:{{ $store.getters["moduleA/getName1"] }},计算属性调用:{{
getName1
}}
</p>
<p>
直接调用:{{ $store.getters["moduleA/getName2"]() }},计算属性调用:{{
getName2
}}
</p>
<p>
直接调用:{{ $store.getters["moduleA/getName3"]("hhh") }},计算属性调用:{{
getName3
}}
</p>
<p v-if="$store.state.moduleA.isShow">努力学习</p>
<button @click="$store.commit('moduleA/changeShow')">
同步方式直接调用
</button>
<button @click="changeShow1">同步方式methods调用</button>
<button @click="changeShow2">异步方式methods调用</button>
</div>
</template>
<script>
export default {
data() {
return {};
},
computed: {
//通常情况都是以计算属性的形式调用
getName() {
return this.$store.state.moduleA.name;
},
//getters的第一种方式
getName1() {
return this.$store.getters["moduleA/getName1"];
},
//getters的第二种方式
getName2() {
//因为第二种方式返回值是一个函数
return this.$store.getters["moduleA/getName2"]();
},
//getters的第三种方式
getName3() {
return this.$store.getters["moduleA/getName3"]("hhh");
},
},
methods: {
//同步方式
changeShow1() {
this.$store.commit("moduleA/changeShow");
},
//异步方式
changeShow2() {
this.$store.dispatch("moduleA/asChangeShow");
},
},
};
</script>
<style>
</style>
注:
1、getters是个数组,用数组的形式调用
2、调用mutations中的方法必须使用commit方法,无论是直接调用还是在actions中调用。mutations是同步的
3、调用actions中的方法必须使用dispatch,actions不能直接修改state,通过commit调用mutations来修改。actions是异步的
4、一般情况下使用mutations来修改state,异步情况才使用actions