四、 Vuex
1. 简介
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,
并以相应的规则保证状态以一种可预测的方式发生变化。
简单来说,用来集中管理数据,类似于React中的Redux,都是基于Flux的前端状态管理框架
2. 基本用法
2.1 安装vuex
cnpm install vuex -D
2.2 步骤
第1步:在src目录创建store.js文件,在main.js中导入并配置store.选项
第2步:编辑App.vue
第3步:编译运行
2.3 编辑store.js文件
Vuex的核心是Store(仓库),相当于是一个容器,一个store实例中包含以下属性的方法:
state 定义属性(状态、数据)
getters 用来获取属性
actions 定义方法(动作)
commit 提交变化,修改数据的唯一方式就是显式的提交mutations
mutations 定义变化
注:不能直接修改数据,必须显式提交变化,目的是为了追踪到状态的变化
2.4 编辑App.vue
在子组件中访问store对象的两种方式:
方式1:通过this.$store访问
方式2:通过mapState、mapGetters、mapActions访问,vuex提供了两个方法:
mapState 获取state
mapGetters 获取getters
mapActions 获取actions
方式1:通过this.$store访问
store.js
/**
* vuex配置
*/
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
//定义属性(数据)
var state = {
count: 6
}
//创建store对象
const store = new Vuex.Store({
state,
})
//导出store对象
export default store;
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store.js' //引入store
new Vue({
store,
//配置store选项,指定为store对象,会自动将store对象注入到所有子组件中,
// 在子组件中通过this.$store访问该store对象
el: '#app',
render: h => h(App)
})
App.vue
<template>
<div id="app">
<p>当前数字为:{{count}}</p>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
computed:{
count(){
return this.$store.state.count;
}
},
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
方式2:通过mapState、mapGetters、mapActions访问
方式2:通过mapState、mapGetters、mapActions访问,vuex提供了两个方法:
mapState 获取state
mapGetters 获取getters
mapActions 获取actions
store.js
/**
* vuex配置
*/
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
//定义属性(数据)
var state = {
count: 6
}
//定义getters
var getters = {
count(state) {
return state.count;
},
isEvenOrOdd(state) {
return state.count % 2 == 0 ? '偶数' : '奇数';
}
}
//定义actions,要执行的操作,如流程判断、异步请求等
const actions = {
// increment(context) { //包含:commit、dispatch、state
// console.log(context);
// context.commmit()
// },
increment({ commit, state }) {
commit('increment'); //提交一个名为increment的变化,名称可自定义,可以认为是类型名
},
decrement({
commit,
state
}) {
if (state.count > 10) {
commit('decrement');
}
},
incrementAsync({
commit,
state
}) {
//异步操作
var p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 3000);
});
p.then(() => {
commit('increment');
}).catch(() => {
console.log('异步操作');
});
}
}
//定义mutations,处理状态(数据)的改变
const mutations = {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
}
//创建store对象
const store = new Vuex.Store({
state,
getters,
actions,
mutations
})
//导出store对象
export default store;
App.vue
<template>
<div id="app">
<button @click="increment">增加</button>
<button @click="decrement">减小</button>
<button @click="incrementAsync">增加</button>
<p>当前数字为:{{count}}</p>
<p>{{isEvenOrOdd}}</p>
</div>
</template>
<script>
// 方法2:(1)
import {mapState,mapGetters,mapActions} from 'vuex'
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
//方法2:(2)
computed:mapGetters([
'count',
'isEvenOrOdd'
]),
methods:mapActions([
'increment',
'decrement',
'incrementAsync'
])
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>