Vuex的状态管理
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
就是一个加强版的data!
在单页应用中会有一个data函数,管理当前应用的状态。
处理大量的需要在组件间传递的数据,直接定义一个全局的data属性保存就行了。
如果我们的页面比较简单,切记千万不要没事找事引入Vuex,我们使用Vuex是因为项目变得复杂之后,有很多数据需要在父组件、子组件和孙组件之间传递,处理起来很繁琐,于是就需要Vuex这样一个可以对这一部分数据进行统一管理的东西,也是响应式
什么情况需要使用Vuex管理状态在多个组件间共享?
大型项目中组件很多,多个组件中共用的数据
例如:用户的登录状态、用户名称、头像、地理位置信息等
例如:商品的收藏、购物车中的物品。
例如:传递组件之间传递层次太多、不相关组件、公用组件
Vuex有点类似cookie和session,session是用于服务器端共享,cookie是用于浏览器的,Vuex是用于前端组件间共享
四个核心概念
Vuex 的四个核心概念分别是:
- The state tree:Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。至此它便作为一个『唯一数据源(SSOT)』而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
- Getters:用来从 store 获取 Vue 组件数据。
- Mutators:事件处理器用来驱动状态的变化。
- Actions:可以给组件使用的函数,以此用来驱动事件处理器 mutations
Vuex和简单的全局对象是不同的,当Vuex从store中读取状态值的时候,若状态发生了变化,那么相应的组件也会高效的更新。并且,改变store中状态的唯一途径就是提交commit mutations。这样便于我们跟踪每一次状态的变化。只要发生了状态的变化,一定伴随着mutation的提交。
文件目录
props传递值
helloword子组件使用Home组件声明的变量,可采用之前学习的组件传递值的方法
Home
组件
<template>
<div class="home">
<h2>这是在单页模板中应用</h2>
<h3>{
{count}}</h3>
<button @click="count--">-</button>
<button @click="count++">+</button>
<!-- 传递count给子组件helloword--->
<HelloWorld :count="count" msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
data() {
return {
count: 0
}
}
}
</script>
helloword
子组件
![](/qrcode.jpg)
<template>
<div class="hello">
<h1>{
{ msg }}</h1>
<h3>在子组件hellword中应用Home中的Data</h3>
<h3>{
{count}}</h3>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
count: Number
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
……
</style>
效果
若About组件想要使用Home组件的count,通过组件传递的方式也可实现,就是有点麻烦,需要传递给中介App组件,App组件再传递给About组件。
Vuex的state传递
因此,在这里可采用Vuex,其配置文件在/store/index.js
import {
createStore } from 'vuex'
export default createStore({
state: {
//任何地方都可使用这个状态管理
num: 0
},
mutations: {
},
actions: {
},
modules: {
}
})
Home.vue
<template>
<div class="home">
<h2>使用全局的状态管理</h2>
<h3>{
{$store.state.num}}</h3>
<button @click="$store.state.num--">-</button>
<button @click="$store.state.num++">+</button>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
}
</script>
About.vue
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{
{$store.state.num}}</h3>
</div>
</template>
效果
Matuations来修改状态
Vuex最好采用Matuations来修改状态,而不是通过组件的形式
index.js
import {
createStore } from 'vuex'
export default createStore({
state: {
//任何地方都可使用这个状态管理
num: 0,
mnum: 0
},
mutations: {
//自动把state的参数传过来
sub(state) {
state.mnum--;
},
add(state) {
state.mnum++;
}
},
actions: {
},
modules: {
}
})
Home.vue
<template>
<div class="home">
<h2>这是在单页模板中应用</h2>
<h3>{
{count}}</h3>
<button @click="count--">-</button>
<button @click="count++">+</button>
<HelloWorld :count="count" msg="Welcome to Your Vue.js App"/>
<hr>
<h2>使用全局的状态管理</h2>
<h3>{
{$store.state.num}}</h3>
<button @click="$store.state.num--">-</button>
<button @click="$store.state.num++">+</button>
<hr>
<h2>使用Mutations来修改状态</h2>
<h3>MNum:{
{$store.state.mnum}}</h3>
<button @click="sub1()">-</button>
<button @click="add1()">+</button>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
data() {
return {
count: 0
}
},
methods: {
add1() {
this.$store.commit('add')
},
sub1() {
this.$store.commit('sub')
},
}
}
</script>
About.vue
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>Num:{
{$store.state.num}}</h3>
<h3>MNum:{
{$store.state.mnum}}</h3>
</div>
</template>
效果
Mutations带参数传递修改状态
index.js
import {
createStore } from 'vuex'
export default createStore({
state: {
//任何地方都可使用这个状态管理
num: 0,
mnum: 0
},
mutations: {
//自动把state的参数传过来
sub(state) {
state.mnum--;
},
add(state) {
state.mnum++;
},
//接收一个参数
sub2(state,count) {
console.log(count);
state.mnum-=count;
},
add2(state,count) {
console.log(count);
state.mnum+=count;
},
//接收多个参数
sub3(state,payload) {
console.log(payload);
state.mnum-=(payload.count+payload.num);
},
add3(state,payload) {
console.log(payload);
state.mnum+=(payload.count+payload.num);
}
},
actions: {
},
modules: {
}
})
Home.vue
<template>
<div class="home">
<hr>
<h2>使用Mutations来修改状态</h2>
<h3>MNum:{
{$store.state.mnum}}</h3>
<button @click="sub1()">-</button>
<button @click="add1()">+</button>
<hr>
<h2>使用Mutations来修改状态带一个参数</h2>
<h3>MNum:{
{$store.state.mnum}}</h3>
<button @click="sub2()">-</button>
<button @click="add2()">+</button>
<hr>
<h2>使用Mutations来修改状态带多个参数</h2>
<h3>MNum:{
{$store.state.mnum}}</h3>
<button @click="sub3()">-</button>
<button @click="add3()">+</button>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
data() {
return {
count: 0
}
},
methods: {
add1() {
this.$store.commit('add')
},
sub1() {
this.$store.commit('sub')
},
add2() {
let count = 2;
this.$store.commit('add2',count)
},
sub2() {
let count = 2;
this.$store.commit('sub2',count)
},
add3() {
let payload = {
count:2, num:1}
this.$store.commit('add3',payload)
},
sub3() {
let payload = {
count:2, num:1}
this.$store.commit('sub3',payload)
//等价于
//this.$store.commit({type:'sub3', payload})
}
}
}
</script>
效果