1. Vuex概念和作用解析
1.1Vuex概念
官方解释:Vuex是一个专为Vue.js应用程序开发的状态管理模式。
- 它采用集中式存储管理应用的所有组件的状态,并以相应的规则保存状态以一种可预测的方式发生变化。
- Vuex也集成到Vue的官方调试工具devtools extension,提供了诸如零配置的time-travel调试、状态快照导入导出等高级调试功能。
个人理解:状态管理
- 状态管理模式、集中式存储管理这些名词听起来就非常高大上,让人难以理解。
- 其实,你可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里。
- 然后,将这个对象放在顶层的Vue实例中,让其它组件可以使用。
- 那么,多个组件是不是就可以共享这个对象中的所有变量属性了呢?
如果这样的话,为什么官方还要专门出一个插件Vuex呢?难道我们不能自己封装一个对象来管理吗?
- 当然可以自己封装一个对象来管理,但是VueJS带给我们最大的遍历是响应式。
- 如果你自己封装一个对象能不能保证里面所有的属性做到响应式呢?当然可以,只是自己封装的稍微麻烦一些。
- 不用怀疑,Vuex就是为了提供这样一个在多个组件间共享状态的插件,我们直接使用即可,不用自己写一个。
假如我们自己封装一个对象,如何封装的?
const sharedObj={
name:"haha",
age:18
}
Vue.prototype.sharedObj=sharedObj;//使用Vue原型,这就可以在其它组件共享使用
//在其它组件可以直接这样用
this.sharedObj.name来使用这对象的属性
注意:这样实现的对象只能在组件共享,还不能做到响应式。这里就不再做多讨论,重点是学习Vuex。
1.2 作用解析
有什么状态是需要我们在多个组件间共享的呢?
- 如果做过大型项目,你一定遇到过多个状态,在多个页面间共享的问题。
- 比如用户的登录状态、用户名称、头像、地理位置信息等。
- 比如商品的收藏、购物车的物品等。
- 这些状态信息,我们都可以统一放在一个地方,对它进行保存和管理,而且它们还是响应式的。
2.单界面到多界面状态管理切换
2.1 单界面状态管理切换
我们知道,要在单个组件中进行状态管理是一件非常简单的事情。
这图片中的三种东西怎么理解呢?
- State:即状态(你可以把它当成组件data中的属性)
- View:视图层,可以针对State的变化,显示不同的信息。
- Actions:这里的Actions主要是用户的各种操作:点击、输入等,会导致状态的变化。
下面一个简单的实例:
<template>
<div id="app">
<h3>{
{count}}</h3>
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
</template>
<script>
// import Home from "./components/Home.vue";
export default {
name: "App",
data: function () {
return {
count: 0,
};
},
methods: {
add: function () {
this.count++;
},
sub: function () {
this.count--;
},
},
};
</script>
<style>
</style>
看到上面的动图,你即可以将:
- count变量当成State
- 按钮的点击事件当作Actions
- 在页面上0、1、2的切换即是针对count的变化,显示不同的内容。
2.2 Vuex的安装以及使用
当在多个页面想要实现共享时,我们会使用Vuex插件,既然它是一个插件,那么它需要下载安装:
npm install vuex --save
这个插件与vue-router插件都是Vue中非常重要的,vue-router在项目中有一个专门的router文件夹管理着路由相关的内容。因此,这里我们也在项目的src文件下创建一个名为store的文件夹并添加index.js文件,方便管理。
看看官方的Vuex状态管理图例:(该图是学习重点,务必记住)
图例解释:
- 在组件中使用dispatch()将交互派遣给Actions。
- 通常Actions只用于处理异步(网络请求等)。
- 若没有异步则组件可以直接使用commit()提交到Mutations。
- 注意:Devtools是帮我们记录状态的,所以务必要经过Mutations这一步,否则无法跟踪记录。
实例:在多组间使用Vuex共享的数据:
下面开始使用Vuex插件:
import Vue from "vue";
import Vuex from "vuex";
// 1.使用Vuex插件
Vue.use(Vuex);
// 2.创建Vuex对象
const store = new Vuex.Store({
state: {
counter:999
},
mutations: {
},
actions: {
},
getters: {
},
modules: {
}
});
// 3.导出Vuex对象,因为Vue实例要使用
export default store;
这是一个比较固定的模板,Vuex实例中的属性基本我们都要用到。然后我们在Vue实例处引入Vuex实例并使用即可。
对象中属性解释:
- state相当于组件的data属性
- mutations相当于methods属性
- actions则只有在使用异步时才使用
- getters相当于组件的computed属性
在Vue实例中引用Vuex实例:
//main.js
import Vue from "vue";
import App from "./App";
import store from "./store/index";
Vue.config.productionTip = false;
new Vue({
el: "#app",
store,
render: h => h(App)
});
在App.vue和Home.vue组件使用Vuex共享的数据:
App.vue:
<template>
<div id="app">
<hr />
<h2>我是App.vue组件</h2>
<h3>我在App.vue组件使用counter: {
{
$store.state.counter }}</h3>
<Home></Home>
</div>
</template>
<script>
import Home from "./components/Home.vue";
export default {
name: "App",
components: {
Home
}
};
</script>
<style></style>
Home.vue:
<template>
<div>
<hr />
<h2>我是App.vue的子组件</h2>
<h2>我在Home.vue组件中使用counter:{
{
$store.state.counter }}</h2>
</div>
</template>
<script>
export default {
};
</script>
<style></style>
运行:
上面两个组件是父子关系。他们都使用了Vuex中共享的counter。
注意:
- $store对象就是我们在store/index.js中创建的Vuex实例,使用跟普通对象一样。
3. Vuex-devtools的安装
(前提是你能使用外国网络,即翻墙)
首先我们在chorme浏览器中:
- 打开设置
- 左下角点击“扩展程序”
- 搜索devtools
- 找到Vue.js的devtools添加扩展
- 重启浏览器,打开检查
上面多了一个Vue,点开即可使用该扩展。
4. 举例查看Vuex是否跟踪记录
这个实例由于没有用到异步操作,所以直接从Component–>Mutations–>State,跳过Actions。这是一个点击按钮实现数字增减的实例。
Store/index.js:
import Vue from "vue";
import Vuex from "vuex";
// 1.使用Vuex插件
Vue.use(Vuex);
// 2.创建Vuex对象
const store = new Vuex.Store({
state: {
counter: 999
},
mutations: {
add(state) {
state.counter++;
},
sub(state) {