Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
就是一个加强版的data!
在单页应用中会有一个data函数,管理当前应用的状态。
处理大量的需要在组件间传递的数据,直接定义一个全局的data属性保存就行了。
如果我们的页面比较简单,切记千万不要没事找事引入Vuex,我们使用Vuex是因为项目变得复杂之后,有很多数据需要在父组件、子组件和孙组件之间传递,处理起来很繁琐,于是就需要Vuex这样一个可以对这一部分数据进行统一管理的东西,也是响应式
什么情况需要使用Vuex管理状态在多个组件间共享?
大型项目中组件很多,多个组件中共用的数据
例如:用户的登录状态、用户名称、头像、地理位置信息等
例如:商品的收藏、购物车中的物品。
例如:传递组件之间传递层次太多、不相关组件、公用组件
Vuex有点类似cookie和session,session是用于服务器端共享,cookie是用于浏览器的,Vuex是用于前端组件间共享
四个核心概念
Vuex 的四个核心概念分别是:
Vuex和简单的全局对象是不同的,当Vuex从store中读取状态值的时候,若状态发生了变化,那么相应的组件也会高效的更新。并且,改变store中状态的唯一途径就是提交commit mutations。这样便于我们跟踪每一次状态的变化。只要发生了状态的变化,一定伴随着mutation的提交。
文件目录
helloword子组件使用Home组件声明的变量,可采用之前学习的组件传递值的方法
Home
组件
<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"/>
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
子组件
<template>
<div class="hello">
<h1>{{ msg }}h1>
<h3>在子组件hellword中应用Home中的Datah3>
<h3>{{count}}h3>
div>
template>
<script>
export default {
name: 'HelloWorld',
props: {
count: Number
}
}
script>
<style scoped lang="scss">
……
style>
效果
若About组件想要使用Home组件的count,通过组件传递的方式也可实现,就是有点麻烦,需要传递给中介App组件,App组件再传递给About组件。
因此,在这里可采用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 pageh1>
<h3>{{$store.state.num}}h3>
div>
template>
效果
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 pageh1>
<h3>Num:{{$store.state.num}}h3>
<h3>MNum:{{$store.state.mnum}}h3>
div>
template>
效果
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>
效果