一、概念
1、Vuex是什么
Vuex 是一个专为Vue.js应用程序开发的状态管理模式
它采用集中式存储管理应用的所有组件的状态 并以相应的规则保证状态以一种可预测的方式发生变化
(官网摘的 可能有些难懂)
上面的状态管理模式中的状态 可以理解为是数据
即 可以将一些共享的数据保存到Vuex
中 以方便程序中的任何组件直接获取或修改公共数据
也就是说 Vuex
相当于是一个全局的共享的数据存储空间 起到了数据仓库的作用
从而实现了数据和组件的分离
在开发中 有时会面临着一些尴尬局面:
比如:父组件要获取孙子组件里的数据
若不借助Vuex 则父组件要借助子组件来传递孙子组件的数据
若有了Vuex 可将孙子组件内的数据放在Vuex里 父组件也从Vuex里拿数据
再比如:组件要获取平级组件里的数据
若不借助Vuex 则父组件要借助中间人来传递数据
若有了Vuex 可将组件内的数据放在Vuex里 其它的组件也从Vuex里拿数据
2、区别
同样是存放数据 data属性和props属性和vuex的区别:
- data存放的是组件私有的数据
- props存放的是父组件传递来的数据
- vuex存放的是组件间共享的数据
二、安装
下载:
npm i vuex -S
安装:
import Vuex from 'vuex'
Vue.use(Vuex)
注:导入Vuex的语句必须放在导入Vue之后
创建Vuex的Store存储区:
const store = new Vuex.Store({
state:
{
count: 0
},
mutations:
{
increment (state)
{
state.count++
}
}
})
Store的state属性 就相当于是data数据
Store的mutations属性 就相当于是methods方法 用于操作state中的数据
最后 将vuex创建的store实例挂载到Vue实例上:
只要挂载到了Vue实例上 那么任何组件都能全局使用store来存取数据了
const vm = new Vue({
el: '#app',
data:{},
methods:{},
store
})
三、使用
1、获取数据
在组件中若要访问Store中的数据 通过$store.state.属性名
即可
main.js:
var store = new Vuex.Store({
state:
{
count: 0
}
})
Test.vue:
<template>
<div>
<h3>{{ $store.state.count }}</h3>
</div>
</template>
2、操作数据
在方法里操作数据的时候 并不推荐直接使用 this.$store.state.名称 来操作数据(虽然也可以成功操作)
这样的话 若因操作导致数据产生了紊乱 无法很快找出是什么组件导致数据产生错误的 因为每个组件都有直接操作数据的方法
既然store是个仓库 那么 可以视为有一个仓库管理员
当组件要操作仓库内的数据时 调用 mutations 提供的方法 让仓库管理员来操作数据 而不是组件自己操作数据
main.js:
(在mutations里就不用this.$store.state.count了 直接state.count就可以 因为已经在store里了)
var store = new Vuex.Store({
state:
{
count: 0
}
mutations:
{
increment(state) {
state.count++
}
}
})
在组件中若要调用mutation中的方法的话 使用this.$store.commit(方法名)
即可 方法名就是在mutations里定义好的方法名
Test.vue:
methods:
{
add() {
this.$store.commit("increment");
}
}
}
3、传递参数
单个参数
方法的第二个位置为传入的参数的形参
main.js:
var store = new Vuex.Store({
state:
{
count: 0
}
mutations:
{
subtract(state, a) {
state.count -= a
}
}
})
在组件内调用方法的时候 在第二个位置传入参数即可
Test.vue:
methods: {
remove() {
this.$store.commit("subtract", 5);
}
}
多个参数
在mutations的函数的参数列表中 最多只支持两个参数
那么 传递对象即可
main.js:
var store = new Vuex.Store({
state:
{
count: 0
}
mutations:
{
subtract(state, obj) {
console.log(obj)
state.count -= (obj.a + obj.b)
}
}
})
调用方法的时候传递一个对象:
对象的属性键值对用花括号包裹
Test.vue:
methods: {
remove() {
this.$store.commit("subtract", { a: 5, b: 10 });
}
}
4、包装数据
在Vuex.Store上还有个getters
属性
该属性只能对外提供获取数据的方法 在方法中return数据即可
注:正如其名 getters并不能修改数据 若要修改 还是得去mutations里定义相应的方法
main.js:
var store = new Vuex.Store({
state:
{
count: 0
},
getters:
{
getCount: function (state) {
return "最新count值:" + state.count
}
}
})
在组件中获取数据的时候 使用$store.getters.方法名
的格式
Test.vue:
<template>
<div>
<h3>{{ $store.getters.getCount }}</h3>
</div>
</template>
getters和过滤器比较类似 都不会修改原数据 而是对原数据进行一次包装 然后返回给调用者
getters和computed属性也比较类似 只要state中的数据发生了变化
若getters引用了该数据 那么在getters中会立即重新求值 无需重新调用
总结:
- 1、通过
this.$store.state.属性名
来获取Vuex中的数据 - 2、组件内若要修改state中的数据 需使用在mutation定义的方法 通过
this.$store.commit(方法名,参数)
的格式调用 - 3、若state的数据在对外提供的时候需再进行一层包装 那么可用getters属性 在里面定义方法 返回数据值即可
在组件中通过this.$store.getters.方法名
获取