类似Flux、Redux数据的单向流动。
安装:
$ cnpm install vuex --save
在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex:
import Vue from ‘vue‘
import Vuex from ‘vuex‘
Vue.use(Vuex)
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
创建一个store.js文件:
import Vuex from "vuex";
const store = new Vuex.Store({
//这里的state必须是JSON,是一个对象。
state: {
count: 0 //这里就是初始值的罗列
},
//突变,罗列所有可能改变state的方法
mutations: {
//没有所谓的大写字母的Type了,就是一个一个函数
add (state) {
state.count++; //直接改变了state中的值,而并不是返回了一个新的state
},
minus (state) {
state.count--;
}
}
});
export default store;
再次强调,我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。
由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutations。
天生任何组件都可以“通天”,没有connect和Provider,仅需要在computed中使用store.state.**字样或者在mehotds中使用store.commit(**)字样即可。
在组件内部使用store很简单,单独引用store即可:
<style scopoed>
</style>
<template>
<div>
我是子组件
<h1>
<button v-on:click="minusnandler">减少</button>
{{count}}
<button v-on:click="addhandler">增加</button>
</h1>
</div>
</template>
<script>
import store from "./store.js";
export default {
computed : {
count(){
return store.state.count;
}
},
methods : {
addhandler(){
store.commit("add");
},
minusnandler(){
store.commit("minus");
}
}
}
</script>
和Redux相比,减少了Action和Reducer。因为Vuex中简化了Store的书写,Store中并不存在这样的写法:
(state,action)=>{
根据action返回新state
}
而是变为了:
new Vuex.Store({
state:{
},
mutations : {
//罗列一些函数,可以直接改变state的值
}
})
还有一种写法,就是在main.js中直接声明使用store,这样.vue组件文件中就没有必要引用store文件了。
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
//这里的state必须是JSON,是一个对象。
state: {
count: 0 //这里就是初始值的罗列
},
//突变,罗列所有可能改变state的方法
mutations: {
//没有所谓的大写字母的Type了,就是一个一个函数
add (state) {
state.count++;
},
minus (state) {
state.count--;
}
}
});
export default store;
main.js:
import Vue from "vue";
import Vuex from "vuex";
import MyCompo from "./MyCompo.vue";
import store from "./store.js";
new Vue({
el : "#app",
store,
data : {
a : 100
},
components : {
MyCompo
}
});
.vue组件文件中,使用this.$store来表示使用的那个全局store
<style scopoed>
</style>
<template>
<div>
我是子组件
<h1>
<button v-on:click="minusnandler">减少</button>
{{count}}
<button v-on:click="addhandler">增加</button>
</h1>
</div>
</template>
<script>
export default {
computed : {
count(){
return this.$store.state.count;
}
},
methods : {
addhandler(){
this.$store.commit("add");
},
minusnandler(){
this.$store.commit("minus");
}
}
}
</script>
在store中如果有依赖于state的值而改变值,相当于是store的computed,此时可以在store中增加一个getters配置项:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
//这里的state必须是JSON,是一个对象。
state: {
count: 0 , //这里就是初始值的罗列,
student : [
{"name" : "小1" , "sex" : "男" },
{"name" : "小2" , "sex" : "女" },
{"name" : "小3" , "sex" : "男" },
{"name" : "小4" , "sex" : "女" }
]
},
//突变,罗列所有可能改变state的方法
mutations: {
//没有所谓的大写字母的Type了,就是一个一个函数
add (state) {
state.count++;
},
minus (state) {
state.count--;
}
},
getters : {
nansheng : state => {
return state.student.filter((item)=>{
return item.sex == "男";
})
}
}
});
export default store;
组件中使用this.$store.getters.**来获得这个值。
<style scopoed>
</style>
<template>
<div>
我是子组件
<h1>
<button v-on:click="minusnandler">减少</button>
{{count}}
<button v-on:click="addhandler">增加</button>
</h1>
<h1>
{{nansheng}}
</h1>
</div>
</template>
<script>
export default {
data(){
return {
m : 6
}
},
computed : {
count(){
return this.$store.state.count;
},
nansheng (){
return this.$store.getters.nansheng
}
},
methods : {
addhandler(){
this.$store.commit("add");
},
minusnandler(){
this.$store.commit("minus");
}
}
}
</script>
如果要发送命令的时候(commit)要带参数上去,此时直接逗号写出即可。在store中,第一个参数必须是state,之后就是你commite时候写带的参数。
this.$store.commit("add" , this.n);
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
//这里的state必须是JSON,是一个对象。
state: {
count: 0 , //这里就是初始值的罗列,
student : [
{"name" : "小1" , "sex" : "男" },
{"name" : "小2" , "sex" : "女" },
{"name" : "小3" , "sex" : "男" },
{"name" : "小4" , "sex" : "女" }
]
},
//突变,罗列所有可能改变state的方法
mutations: {
//没有所谓的大写字母的Type了,就是一个一个函数
add (state , n) {
state.count+= n;
},
minus (state) {
state.count--;
}
},
getters : {
nansheng : state => {
return state.student.filter((item)=>{
return item.sex == "男";
})
}
}
});
export default store;
只能携带一个值,所以我们要传输很多值的时候,采用对象封装。
this.$store.commit("add" , {n : this.n});
然后使用对象来枚举即可:
mutations: {
//没有所谓的大写字母的Type了,就是一个一个函数
add (state , payload) {
state.count+= payload.n;
},
minus (state) {
state.count--;
}
},
Redux中的action + dispatch的模式现在在vuex中用于异步commit的发送。
也就是说:
比如现在有一个需求,点击按钮之后加上文本文件中写明的数字:
<style scopoed>
</style>
<template>
<div>
我是子组件
<h1>
<button v-on:click="minusnandler">减少</button>
{{count}}
<button v-on:click="addhandler">增加</button>
</h1>
<h1>
{{nansheng}}
</h1>
</div>
</template>
<script>
export default {
data(){
return {
m : 6,
n : 0
}
},
computed : {
count(){
return this.$store.state.count;
},
nansheng (){
return this.$store.getters.nansheng
}
},
methods : {
addhandler(){
this.$store.dispatch("add"); //添加的数字写在文本文件中了,是异步读取的,所以不能直接commit
},
minusnandler(){
this.$store.commit("minus");
}
}
}
</script>
此时store.js:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
//这里的state必须是JSON,是一个对象。
state: {
count: 0 , //这里就是初始值的罗列,
student : [
{"name" : "小1" , "sex" : "男" },
{"name" : "小2" , "sex" : "女" },
{"name" : "小3" , "sex" : "男" },
{"name" : "小4" , "sex" : "女" }
]
},
//突变,罗列所有可能改变state的方法
mutations: {
//没有所谓的大写字母的Type了,就是一个一个函数
add (state , n ) {
state.count += n;
},
minus (state) {
state.count--;
}
},
actions : {
add(context,payload){
$.get("api.txt",function(data){
context.commit(‘add‘,Number(data));
});
}
},
getters : {
nansheng : state => {
return state.student.filter((item)=>{
return item.sex == "男";
})
}
}
});
export default store;
至此,在Vuex.store()函数中配置参数有哪些?state、mutations、getters、actions。
当项目很大的时候需要在不同的位置写store中的4个东西state、mutations、actions、getters。此时使用内置的modules属性就能合并:
import Vue from "vue";
import Vuex from "vuex";
import counter from "./counter.js";
Vue.use(Vuex);
const store = new Vuex.Store({
modules : {
counter
}
});
export default store;
couter.js文件:
export default {
//这里的state必须是JSON,是一个对象。
state: {
count: 0 , //这里就是初始值的罗列,
student : [
{"name" : "小1" , "sex" : "男" },
{"name" : "小2" , "sex" : "女" },
{"name" : "小3" , "sex" : "男" },
{"name" : "小4" , "sex" : "女" }
]
},
//突变,罗列所有可能改变state的方法
mutations: {
//没有所谓的大写字母的Type了,就是一个一个函数
add (state , n ) {
state.count += n;
},
minus (state) {
state.count--;
}
},
actions : {
add(context,payload){
$.get("api.txt",function(data){
context.commit(‘add‘,Number(data));
});
}
},
getters : {
nansheng : state => {
return state.student.filter((item)=>{
return item.sex == "男";
})
}
}
}
原文:https://www.cnblogs.com/zykzyk/p/11390627.html