理解、明白Vuex的作用
一、Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。**
1. 它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
2. Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
状态管理到底是什么?
状态管理模式、集中式存储管理这些名词听起来就非常高大上,让人捉摸不透。
其实,你可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面。然后,将这个对象放在]顶层的Vue实例中,让其他组件可以使用。那么,多个组件是不是就可以共享这个对象中的所有变量属性了呢?
ex:有一个count变量,在多个组件中都需要被使用到,那么可以在Veu.prototype上定义一个count即可,但是这样做,无法实现响应式处理,那么Vuex 应运而生.
等等!如果是这样的话,为什么官方还要专门出一个插件Vuex呢?难道我们不能自己封装一个对象来管理吗?
当然可以,只是我们要先想想Vue.js带给我们最大的便利是什么呢?没错,就是响应式。如果你自己封装实现一个对象能不能保证它里面所有的属性做到响应式呢?当然也可以,只是自己封装可能稍微麻烦一些。不用怀疑,Vuex就是为了提供这样一个在多个组件间共享状态的插件,用它就可以了。
二、管理什么状态呢?
但是,有什么状态是需要我们在多个组件间共享的呢?
- 如果你做过大型开放,你一定遇到过多个状态,在多个界面间的共享问题。比如用户的登录状态、用户名称、头像、地理位置信息等等。
- 比如商品的收藏、购物车中的物品等等。
- 这些状态信息,我们都可以放在统一的地方,对它进行保存和管理,而且它们还是响应式的(待会儿我们就可
以看到代码了,莫着急)。
OK,从理论上理解了状态管理之后,让我们从实际的代码再来看看状态管理。
毕竟,Talk is cheap, Show me the code.(来自Linux) //说话很便宜,给我看看代码
三、单界面的状态管理
我们知道,要在单个组件中进行状态管理是一件非常简单的事情,什么意思呢?
State :驱动应用的数据源。(你姑且可以当做就是data中的属性)
View :视图层,可以针对State的变化,显示不同的信息,以声明方式将 state 映射到视图。(这个好理解吧? )
Actions :响应在 view 上的用户输入导致的状态变化,主要是用户的各种操作,点击、输入等等,会导致状态的改变。
link:官网参考
State-->>View // 状态可以改变视图
View-->>Actions // 视图可以产生行为(例如点击事件)
Actions-->>State // 行为可以改变状态
// 这样就形成了闭环
<template>
<div id="app">
<h2>{{message}}</h2> //View
<h2>{{counter}}</h2>
<button @click="counter++">+</button>//Actions
<button @click="counter--">-</button>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return {
message:"我是App组件",//State
counter: 0
}
}
}
</script>
四、多界面状态管理
Vue已经帮我们做好了单个界面的状态管理,但是如果是多个界面呢?
- 多个视图都依赖同一个状态(一个状态改了,多个界面需要进行更新)
- 不同界面的Actions都想修改同一个状态( Home.vue需要修改,Profile.vue也需要修改这个状态)
也就是说对于某些状态(状态1/状态2/状态3)来说只属于我们某一个视图,但是也有一些状态(状态a/状态b/状态c)属于多个视图共同想要维护的
- 状态1/状态2/状态3你放在自己的房间中,你自己管理自己用,没问题。
- 但是状态a/状态b/状态c我们希望交给一个大管家来统一帮助我们管理!!!
- 没错,Vuex就是为我们提供这个大管家的工具。
全局单例模式(大管家)
- 我们现在要做的就是将共享的状态抽取出来,交给我们的大管家,统一进行管理。
- 之后,你们每个视图,按照我规定好的规定,进行访问和修改等操作。(不要随意修改,否则后期调试时很容易出问题)
这就是Vuex背后的基本思想。
五、安装使用Vuex
1.NPM
npm install vuex --save
2.在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex
** in main.js中**
// 但是虽然可以这样做,并且能正常使用,但是如果router、vuex等都在main中配置,
// main.js会越来越大,不方便管理
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
所以,我们创建src/store/index.js(store-仓库,约定俗成)
import Vue from 'vue'
import Vuex from 'vuex'
// 1、安装插件
Vue.use(Vuex)
// 2、创建对象,这里并不是直接使用store,二是使用其中的一个Store类
const store=new Vuex.Store({
state: {
// 存贮公共数据的地方
counter: 100,
},
})
// 3、导出对象
export default store
并在main.js中导入、挂载
import store from './store/index'
new Vue({
store,// 挂载:Vue.peototype.$store=store
render: h => h(App),
}).$mount('#app')
//
这样就可以在人已组建访问到vuex的counter属性了
<h3>{{ $store.state.counter }}</h3>
3.Devtools-记录修改state状态的(浏览器)插件
Vue.js devtools 5.3.4,跟踪每一次提交的状态
1).在mutations中定义方法
const store = new Vuex.Store({
mutations: {
// 默认会有state参数
increment(state) {// 变更状态,更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
state.counter++
},
decrement(state) {
state.counter--
}
}
})
2).在组件中定义好方法,在发放中进行提交
<script>
export default {
methods: {
addition() {
this.$store.commit("increment");
},
subtraction() {
this.$store.commit("decrement");
}
}
};
</script>
3).就可以利用devtools插件跟踪state状态了
六、小结
1.提取出一个公共的store对象,用于保存在多个组件中共享的状态
⒉.将store对象放置在new Vue对象中,这样可以保证在所有的组件中都可以使用到
3.在其他组件中使用store对象中保存的状态即可
通过this.$store.state.属性的方式来访问状态,
通过this.$store.commit(‘mutation中方法’)来修改状态
注意事项:
我们通过提交mutation的方式,而非直接改变store.state.count。
这是因为Vuex可以更明确的追踪状态的变化,所以不要直接改变store.state.count的值。