一、Vuex的基本使用步骤
1.1Vuex概述
组件之间共享数据的方式
父向子传值:v-bind属性绑定
子向父传值:v-on事件绑定
兄弟传值:EventBus
- $on 接收数据的那个组件
- $emit 发送数据的那个组件
Vuex是什么?
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
使用Vuex统一管理状态的好处
能够在vuex中集中管理共享的数据,易于开发和后期维护
能够高效地实现组件之间的数据共享,提高开发效率
存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步
什么样的数据适合存储到vuex中
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中,对于组件中的 私有数据,依旧存储在自身data中即可
1.2Vuex的基本使用
安装vuex依赖包
npm install vuex --save
导入vuex包
import Vuex from 'vuex'
vue.use(Vuex)
创建store对象
const store = new Vuex.Store({
//state中存放的就是全局共享的数据
state:{count:0}
})
将store对象挂载到vue实例
new Vue ({
el:'#app',
render:h=>h(app),
router,
//将创建的共享数据对象,挂载到vue实例中
//所有的组件就可以直接从store中获取全局的数据了
store
})
二、Vuex的核心概念
2.1State
State提供唯一的公共数据,所有共享的数据都要统一放到Store的State中进行存储
组件访问 State中数据的第一种方式:
this.$stoter.state.全局数据名称
组件访问 State中数据的第二种方式:
1.从vuex中按需导入mapState函数
import {mapState} from 'vuex'
通过导入的mapState函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性:
2.将全局数据,映射为当前组件的计算属性
computed:{
...mapState(['count'])
}
代码示例:
- 初始化一个测试项目demo1,注意安装vuex
- components中新建两个子组件Son1.vue和Son2.vue
- App.vue中引入两个子组件并注册
<template>
<div id="app">
<Son1></Son1>
<Son2></Son2>
</div>
</template>
<script>
import Son1 from "./components/Son1.vue";
import Son2 from "./components/Son2.vue";
export default {
name: "App",
components: {
Son1,
Son2
}
};
</script>
- store/index.js新建公共的数据模型
export default new Vuex.Store({
state: {
num: 0
},
。。。
});
- 方式1引入公共数据
Son1.vue中使用num
<template>
<div>
子组件1
<p>{{$store.state.num}}</p>
</div>
</template>
- 方式2引入公共数据
<!-- 子组件1 -->
<template>
<div>
子组件1
<p>{{num}}</p>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
data() {
return {};
},
computed: {
...mapState(["num"])
}
};
</script>
同理,Son2.vue也是如此使用。
2.2Mutation
Mutation用于变更Store中的数据
1.只能通过mutation变更Store数据,不可以直接操作Store中的数据
2.通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化
触发mutation的第一种方式
this.$store.commit()
触发mutation的第二种方式
1.从vuex中按需导入mapMutations函数
import {mapMutations} from ‘vuex’
通过刚才导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods
2.将指定的mutations函数,映射为当前组件的methods函数
methods:{
...mapMutations(['add','addN'])
}
代码示例:
mutations第一种使用方式
store/index.js中定义如下:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
num: 0
},
mutations: {
addHandle(state) {
state.num++;
},
addHandle2(state, arg) {
state.num += arg;
}
},
actions: {},
modules: {}
});
Son1.vue中调用如下:
<!-- 子组件1 -->
<template>
<div>
子组件1
<button @click="clickHandle">点击增加1</button>
<button @click="clickHandle2">点击传递参数</button>
<p>{{$store.state.num}}</p>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
clickHandle: function() {
this.$store.commit("addHandle");
},
clickHandle2: function() {
this.$store.commit("addHandle2", 2);
}
}
};
</script>
此时Son1.vue中点击按钮1,页面显示的数字就会增加1,点击按钮2,页面显示的数字就会增加2.
mutations第二种使用方式
store/index.js中定义如下:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
num: 0
},
mutations: {
addHandle(state) {
state.num++;
},
addHandle2(state, arg) {
state.num += arg;
}
},
actions: {},
modules: {}
});
Son1.vue中调用如下:
<!-- 子组件1 -->
<template>
<div>
子组件1
<button @click="clickHandle">点击增加1</button>
<button @click="clickHandle2">点击传递参数</button>
<p>{{$store.state.num}}</p>
<!-- <p>{{num}}</p> -->
</div>
</template>
<script>
import { mapMutations } from "vuex";
export default {
data() {
return {};
},
methods: {
...mapMutations(["addHandle", "addHandle2"]),
clickHandle: function() {
this.addHandle();
},
clickHandle2: function() {
this.addHandle2(2);
}
}
};
</script>
2.3Action
初步使用:
用来写异步代码
在store/index.js中实现代码如下:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
num: 0
},
mutations: {
addHandle(state) {
state.num++;
}
},
actions: {
addSync(context) {
setTimeout(() => {
context.commit("addHandle");
}, 1000);
}
},
modules: {}
});
Son1.vue中代码如下:
<template>
<div>
子组件1
<button @click="clickHandle">点击增加1</button>
<p>{{$store.state.num}}</p>
</div>
</template>
<script>
import { mapMutations } from "vuex";
export default {
data() {
return {};
},
methods: {
clickHandle: function() {
this.$store.dispatch("addSync");
}
}
};
</script>
此时点击按钮会隔一秒数据加一。
异步传参:
store/index.js中代码如下:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
num: 0
},
mutations: {
addHandle(state, arg) {
state.num += arg;
}
},
actions: {
addSync(context, arg) {
setTimeout(() => {
context.commit("addHandle", arg);
}, 1000);
}
},
modules: {}
});
Son1.vue中代码如下:
<!-- 子组件1 -->
<template>
<div>
子组件1
<button @click="clickHandle">点击增加1</button>
<p>{{$store.state.num}}</p>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
clickHandle: function() {
this.$store.dispatch("addSync", 2);
}
}
};
</script>
action第二种调用方式:
store/index.js中代码如下:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
num: 0
},
mutations: {
addHandle(state, arg) {
state.num += arg;
}
},
actions: {
addSync(context, arg) {
setTimeout(() => {
context.commit("addHandle", arg);
}, 1000);
}
},
modules: {}
});
Son1.vue中代码如下:
<!-- 子组件1 -->
<template>
<div>
子组件1
<button @click="clickHandle">点击增加1</button>
<p>{{$store.state.num}}</p>
</div>
</template>
<script>
import { mapActions } from "vuex";
export default {
data() {
return {};
},
methods: {
...mapActions(["addSync"]),
clickHandle: function() {
this.addSync(2);
}
}
};
</script>
2.4Getter
getter主要是对store中的数据进行加工处理包装,不会修改store中的数据。
它类似于计算属性,store中的数据发生变化,getter中的数据也会发生变化。
store/index.js中使用getters进行定义
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
num: 10
},
mutations: {
},
actions: {
},
getters: {
dataRes(state) {
return "修饰后的结果" + state.num;
}
},
modules: {}
});
- 组件中通过方式一调用
<p>{{$store.getters.dataRes}}</p>
- 组件中通过方式二调用
<!-- 子组件1 -->
<template>
<div>
子组件1
<p>{{dataRes}}</p>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
data() {
return {};
},
methods: {},
computed: {
...mapGetters(["dataRes"])
}
};
</script>