单页面状态管理
我们看下面这张图片:
- State:表示状态,例如一些变量
- View:视图层。可以针对State的变化,显示不同的信息
- Actions:代表各种事件,例如:点击,输入等,会导致状态的变化
下面来看一个例子:
<template>
<div id="app">
<h2>{{ count }}</h2>
<button @click="count++">+</button>
<button @click="count--">-</button>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
count: 0
};
},
};
</script>
<style>
</style>
在这个例子中,State就是count变量,count需要在页面中进行展示,就是我们的View部分,当用户通过按钮改变count的值时,count的状态就会改变,这就是Actions。
多页面状态管理
如果我们的应用是多界面的,不同界面的Actions都想修改同一个状态,这时候就需要用到vuex
。
Vuex状态管理图
Vuex的核心概念
-
this.$store:我们可以通过this.$store在vue的组件中获取vuex的实例。
-
State:vuex中的数据源,我们可以通过this.$store.state获取我们在vuex中声明的全局变量的值。
-
Getter:相当于vue中的computed,及计算属性,可以用于监听、计算 state中的值的变化。
-
Mutation:vuex中去操作数据的方法(只能同步执行)。
-
Action:用来操作Mutation 的动作,他不能直接去操作数据源,但可以把mutation变为异步的。
-
Module:模块化,当应用足够大的时候,可以把vuex分成多个子模块。
使用vuex实现多页面状态管理
首先,提取出一个公共的store对象,用于保存多个组件中共享的状态。store对象放置在vuex对象中,可以保证所有的组件都可以使用到。
const store = new Vuex.Store({
state: {
count: 0
},
})
然后就可以在其他组件中使用store对象获取state对象并修改state对象的状态。
- 通过this.$store.state属性来访问状态
- 通过this.$store.commit(‘mutations中的 方法名’)来修改状态
具体代码如下:
App.vue
<template>
<div id="app">
<h2>App组件</h2>
<h2>{{ $store.state.count }}</h2>
<button @click="jia">+</button>
<button @click="jian">-</button>
<h2>HelloVueX组件</h2>
<hello-vue-x></hello-vue-x>
</div>
</template>
<script>
import HelloVueX from "./components/HellowVuex.vue";
export default {
name: "App",
components: {
HelloVueX,
},
methods: {
jia() {
// 通过commit方法调用vuex的mutations中的方法
// this.$store.commit("mutations中的方法名");
this.$store.commit("add");
},
jian() {
this.$store.commit("sub");
},
},
};
</script>
HelloVuex.vue
<template>
<div>{{ $store.state.count }}</div>
</template>
<script>
export default {
name: "HelloVueX",
};
</script>
vuex的index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 1.安装插件
Vue.use(Vuex)
// 2.创建vuex对象
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
// 定义方法
add(state) {
state.count++
},
sub(state) {
state.count--
}
},
actions: {
// 进行异步操作
},
getters: {
},
modules: {
}
})
// 3.导出store对象
export default store
运行结果如下:
getters
getters相当于vue中的computed,及计算属性,可以用于监听、计算 state中的值的变化。
getters: {
// 类似于计算属性,对state中的对象作修改
powerCount(state) {
return state.count * state.count
},
getHeight(state) {
return state.students.filter(s => {
return s.height > 175
})
},
},
getters中定义的方法可以传入一个getters参数,之后在这个方法中可以调用getters的其他方法。
getters: {
// 类似于计算属性,对state中的对象作修改
powerCount(state) {
return state.count * state.count
},
getHeight(state) {
return state.students.filter(s => s.height > 175)
},
// 这里可以传入一个getters参数,在这个方法中可以调用getters的其他方法
getHeightLen(state, getters) {
return getters.getHeight.length
},
},
getters也可以通过传入函数作为参数。
getters: {
// 类似于计算属性,对state中的对象作修改
moreHeight(state) {
return function (height) {
return state.students.filter(s => s.height > height)
}
}
},
mutations
Vuex中修改State中对象的唯一方法就是通过mutations。mutations包括两部分:事件类型和回调函数。
add(state) {
state.count++
},
mutations在修改state对象时可以携带额外的参数,这些参数被称为是mutations的载荷(Payload)
App.vue
<template>
<div id="app">
<h2>App组件</h2>
<h2>{{ $store.state.count }}</h2>
<button @click="jia">+</button>
<button @click="jian">-</button>
<button @click="jia5(5)">+5</button>
<h2>HelloVueX组件</h2>
<hello-vue-x></hello-vue-x>
<h2>getters</h2>
<p>{{ $store.getters.powerCount }}</p>
<p>身高大于175的学生{{ $store.getters.getHeight }}</p>
<p>身高大于175的学生的个数:{{ $store.getters.getHeightLen }}</p>
<p>身高大于170的学生(手动传参){{ $store.getters.moreHeight(170) }}</p>
<button @click="addStu({ id: 5, name: '七七', height: 190 })">
添加学生
</button>
</div>
</template>
<script>
import HelloVueX from "./components/HellowVuex.vue";
export default {
name: "App",
components: {
HelloVueX,
},
data() {
return {};
},
methods: {
jia() {
// 通过commit方法调用vuex的mutations中的方法
// this.$store.commit("mutations中的方法名");
this.$store.commit("add");
},
jian() {
this.$store.commit("sub");
},
jia5(count) {
this.$store.commit("add5", count);
},
addStu(stu) {
this.$store.commit("addStudent", stu);
},
},
};
</script>
<style>
</style>
index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 1.安装插件
Vue.use(Vuex)
// 2.创建vuex对象
const store = new Vuex.Store({
state: {
count: 0,
students: [
{ id: 1, name: "张三", height: 185 },
{ id: 2, name: "李四", height: 170 },
{ id: 3, name: "王五", height: 165 },
{ id: 4, name: "赵六", height: 183 },
]
},
mutations: {
// 定义方法
add(state) {
state.count++
},
sub(state) {
state.count--
},
add5(state, count) {
state.count += count
},
addStudent(state, stu) {
state.students.push(stu)
}
},
actions: {
// 进行异步操作
},
getters: {
// 类似于计算属性,对state中的对象作修改
powerCount(state) {
return state.count * state.count
},
getHeight(state) {
return state.students.filter(s => s.height > 175)
},
// 这里可以传入一个getters参数,在这个方法中可以调用getters的其他方法
getHeightLen(state, getters) {
return getters.getHeight.length
},
moreHeight(state) {
return function (height) {
return state.students.filter(s => s.height > height)
}
}
},
modules: {
}
})
// 3.导出store对象
export default store
actions
如果我们希望在Vuex中进行一些异步操作,比如网络请求,这时候就需要actions。actions类似于mutations,区别就是actions可以进行异步操作。