Vuex
Vuex是一个针对Vue.js开发的状态管理模式。说简单点儿就是一个工具,可以管理(修改或设置)所有组件用到的数据,而不需要借助之前的event bus或者props在组件间传值。
我们可以用公司举个例子:公司有个仓库
1.State(公司的仓库)
2.Getter(只能取出物品,包装一下,不能改变物品任何属性)
3.Muitation(仓库管理员,只有他可以直接存储到仓库)
4.Action(公司的物料采购员,负责从外面买东西和接货, 要往仓库存东西,告诉仓库管理员要存什么)
非常要注意的地方:只要刷新或者退出浏览器,仓库清空。
Vuex使用场景
大型单页应用程序,存在多组件共享数据的时候,需要用到
Vuex 核心内容
创建一个小小的Demo
# 安装 vuex
npm i vuex --save
在src
里面创建vuex/store.js
store (一个容器对象,存储Vuex中的state,mutations,actions,getters等)
state (一个保存数据的对象,对象中的数据可以供所有组件使用)
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state = {
count: 3
};
const mutations = {
add(state) {
state.count++;
},
reduce(state) {
state.count--;
}
};
export default new Vuex.Store({
state,
mutations
})
在src
里面创建components/Count.vue
<template>
<div>
<h2>{{msg}}</h2>
<hr>
<h3>{{$store.state.count}}</h3>
<p>
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
</div>
</template>
<script>
import store from '@/vuex/store'
export default {
name: "Count",
data() {
return {
msg: 'hello Vuex'
}
},
store
}
</script>
<style scoped>
</style>
修改路由
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Count from '@/components/Count'
Vue.use(Router);
export default new Router({
routes: [
{
path: '/hello',
name: 'HelloWorld',
component: HelloWorld
}, {
path: '/',
name: 'Count',
component: Count
}
]
})
mapState
辅助函数
使用count
{{count}}
两种方法:
-
需要一个计算属性
那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态
每当
store.state.count
变化的时候,都会重新求取计算属性,并且触发更新相关联的 DOM。
computed: {
count() {
return this.$store.state.count;
}
}
- 引入mapState
import {mapState} from 'vuex'
计算属性
computed: mapState({ count: state => state.count}),
或者这样
computed: mapState(['count']),
都行
mapMutations
函数传参数
mutations(一个对象,保存的是更改state的函数,也只有它能更改state中的值,触发方式this.$store.commit('函数名',参数))
store.js 记得导出
const mutations = {
add(state,n) {
state.count+=n;
},
reduce(state) {
state.count--;
}
};
Count.vue
<p>
<button @click="$store.commit('add',19)">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
第二种引入
<button @click="add(20)">+</button>
<button @click="reduce">-</button>
引入mapMutations
import {mapState, mapMutations} from 'vuex'
methods: mapMutations(['add', 'reduce'])
Getters
计算属性过滤
getters(一个对象,保存的是一些类似与计算属性的函数,可以通过他们得到任何依赖于state的新的数据)
store.js 记得导出
const getters = {
count: function (state) {
return state.count += 100;
},
count: state => state.count += 100
};
Count
computed: {
//对象展开运算符 我们需要使用一个工具函数将多个对象合并为一个,以使我们可以将最终对象传给 computed 属性。
...mapState(['count']),
count() {
return this.$store.getters.count;
}
},
mapGetters
辅助函数
引入
import {mapState, mapMutations,mapGetters} from 'vuex'
计算属性
computed: {
...mapState(['count']),
// count() {
// return this.$store.getters.count;
// }
...mapGetters(['count'])
},
action
异步修改状态
actions(一个对象,保存的是触发mutations的函数,让mutations去修改state中的值)
store.js 记得导出
const actions = {
addAction(content) {
content.commit('add', 10),
setTimeout(() => {
content.commit('reduce')
}, 5000)
console.log('我比reduce先执行');
},
reduceAction({commit}) {
commit('reduce');
}
};
Count
使用
<p>
<button @click="addAction">+</button>
<button @click="reduceAction">-</button>
</p>
引用
import {mapState, mapMutations,mapGetters,mapActions} from 'vuex'
方法
methods: {
...mapMutations(['add', 'reduce']),
...mapActions(['addAction','reduceAction'])
}
Module
模块组
store
const moduleA={
state,
mutations,
getters,
actions
};
export default new Vuex.Store({
modules:{a:moduleA}
})
使用
<h3>{{$store.state.a.count}}--{{count}}</h3>
{{count}}不能直接使用
要用计算属性
// computed: {
// count() {
// return this.$store.state.a.count;
// }
// }
Vuex模板
src/vuex/store.js
import Vuex from 'vuex'
import Vue from 'vue'
import axios from 'axios'
Vue.use(Vuex);
const state = {
todos: [
{id: 1, title: 'Todo One'},
{id: 2, title: 'Todo Two'}
]
};
const mutations = {
setTodos(state, todos) {
state.todos = todos;
},
post(state,todo){
state.todos.unshift(todo);
}
};
const getters = {
getAllTodos(state) {
return state.todos;
}
};
const actions = {
async getAllTodos({commit}) {
const res = await axios.get('http://jsonplaceholder.typicode.com/todos');
console.log(res);
commit('setTodos', res.data)
} ,
async addTodo({commit},todo) {
const res = await axios.get('http://jsonplaceholder.typicode.com/todos',todo);
console.log(res);
commit('post', res.data)
}
};
export default new Vuex.Store({state,mutations,actions,getters})
导入
import store from '@/vuex/store'
import {mapGetters,mapActions} from 'vuex'
Vue-Todos
安装Vuex
npm i vuex --save
npm i axios --save