前言
- 代码都上传到GitHub中 ,请看GitHub中的day08_/02_learn_vuex githua代码传送地:https://github.com/fengfanli/learn_vue
一、项目构建
1. 项目搭建
- 使用脚手架2版本创建项目:
vue init webpack 02_learn_vuex
- 安装冲的各个参数选择
- 查看项目结构
- 安装vuex:
npm install vuex@3.0.1
,我这里指定了版本
2. vuex配置
新建目录 store和js文件 index.js,如下
store/index.js
内容
其实 创建store
对象中的属性,是固定的,就以下几个:state、mutations、actions、getters、modules
。import Vue from 'vue' import Vuex from 'vuex' // 1. 安装插件 Vue.use(Vuex) // 2. 创建对象 const store = new Vuex.Store({ state: { }, mutations: { }, actions: { }, getters: { }, modules: { } }) // 3. 导出store export default store
配置main.js 。
到此 vuex配置结束
二、vuex 初始用
1. 不使用vuex的状态共享
i、逻辑与代码
- 逻辑
- 在
APP.vue
中 写了一个属性 counter
,在App.vue
中使用插值表达式
去显示, - 我又写了一个
HelloVuex.vue
组件,想显示App.vue 组件
中 的`属性 counter,然后我可以用父传子传参进行传过去。
- 代码如下:
App.vue
<template> <div id="app"> <h2>{ {message}}</h2> <h2>{ {counter}}</h2> <button @click="counter++">+</button> <button @click="counter--">-</button> <hello-vuex :counter="counter"/> </div> </template> <script> import HelloVuex from "./components/HelloVuex"; export default { name: 'App', data() { return { message: '我是APP组件', counter: 0 } }, components: { HelloVuex } } </script> <style> </style>
HelloVuex.vue
代码<template> <div> <h2>{ {counter}}</h2> </div> </template> <script> export default { name: "HelloVuex", props: { counter: Number } } </script> <style scoped> </style>
界面显示
点击+和-,两个数字会实时改变。
ii、延伸的问题思考
- 上面在HelloVuex.vue组件中显示App.vue组件中的数据。
- 其实是在哎App.vue组件中引入了HelloVuex.vue组件,然后进行父对子传参。
- 但是如果不在App.vue组件中引入了HelloVuex.vue组件,不进行父对子传参,那应该怎么在HelloVuex.vue组件中显示App.vue组件中的counter数据呢,其实就可以用vuex来进行显示了,
- 那vuex是个啥呢,请看下面的介绍。
2. vuex介绍
白话一点:就是一个存放共用数据
的一个框架。
vuex官网:https://vuex.vuejs.org/zh/
- 官方解释:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
- 它采用
集中式存储管理 应用的所有组件的状态
,并以相应的规则保证状态以一种可预测的方式发生变化。 - Vuex 也集成到 Vue 的官方调试工具
devtools extension
,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
- 状态管理到底是什么?
状态管理模式
、集中式存储管理
这些名词听起来就非常高大上,让人捉摸不透。- 其实,你可以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面。
- 然后,将这个对象放在顶层的Vue实例中,让其他组件可以使用。
- 那么,多个组件是不是就可以共享这个对象中的所有变量属性了呢?
- 等等,如果是这样的话,为什么官方还要专门出一个插件Vuex呢?难道我们不能自己封装一个对象来管理吗?
- 当然可以,只是我们要先想想VueJS带给我们最大的便利是什么呢?没错,就是响应式。
- 如果你自己封装实现一个对象能不能保证它里面所有的属性做到响应式呢?当然也可以,只是自己封装可能稍微麻烦一些。
- 不用怀疑,Vuex就是为了提供这样一个在多个组件间共享状态的插件,用它就可以了。
- 什么状态时需要我们在多个组件间共享的呢?
- 如果你做过大型开放,你一定遇到过多个状态,在多个界面间的共享问题。
- 比如用户的登录状态、用户名称、头像、地理位置信息等等。
比如商品的收藏、购物车中的物品等等。 - 这些状态信息,我们都可以放在统一的地方,对它进行保存和管理,而且它们还是响应式的(待会儿我们就可以看到代码了,莫着急)。
OK,从理论上理解了状态管理之后,让我们从实际的代码再来看看状态管理。
毕竟,Talk is cheap, Show me the code.(来自Linus)我们先来看看但界面的状态管理
我们知道,要在单个组件中进行状态管理是一件非常简单的事情
什么意思呢?我们来看下面的图片。这图片中的三种东西,怎么理解呢?
State
:不用多说,就是我们的状态。(你姑且可以当做就是data中的属性)View
:视图层,可以针对State的变化,显示不同的信息。(这个好理解吧?)Actions
:这里的Actions主要是用户的各种操作:点击、输入等等,会导致状态的改变。
- 写点代码,加深理解:看下下边的代码效果,
3. 对2.1.1案例使用vuex操作
i、上代码
store/index.js
import Vue from 'vue' import Vuex from 'vuex' // 1. 安装插件 Vue.use(Vuex) // 2. 创建对象 const store = new Vuex.Store({ state: { counter: 1000 }, mutations: { }, actions: { }, getters: { }, modules: { } }) // 3. 导出store export default store
App.vue
<template> <div id="app"> <h2>----------------App 内容-------------</h2> <h2>{ {message}}</h2> <h2>{ {$store.state.counter}}</h2> <button @click="$store.state.counter++">+</button> <button @click="$store.state.counter--">-</button> <h2>----------------Hello Vuex 内容-------------</h2> <!--子组件能调用父组件的属性,是因为父组件向子组件传值了,是有关系的,但是如果没有关系,就要使用vuex--> <!-- <hello-vuex :counter="counter"/>--> <hello-vuex/> </div> </template> <script> import HelloVuex from "./components/HelloVuex"; export default { name: 'App', data() { return { message: '我是APP组件', counter: 0 } }, methods: { }, components: { HelloVuex } } </script> <style> </style>
components/HelloVuex.vue
<template> <div> <!-- <h2>{ {counter}}</h2>--> <h2>{ {$store.state.counter}}</h2> </div> </template> <script> export default { name: "HelloVuex", props: { counter: Number } } </script> <style scoped> </style>
效果和3.1.1一样,如下
ii、反思问题
上面的这种操作是可以的,直接操作 vuex
中 state
中的数据。
但是是不推荐的,为什么不推荐呢,就设计到了 vuex 的原理。看下一节vuex的状态管理
三、Vuex状态管理图
先看一副官方给出的图片:
- 虚线方框 是vuex 的三个状态:state、mutations、actions。
- 下面开始对图讲解:
- 最左边的
Vue component
可以直接使用虚线中下面vuex 中的 state
,但是官方不推荐这样使用,官方推荐Vue component
先dispatch
到vuex的 actions
中,在commit
到vuex 的 mutations
中,通过mutations
修改·state·。这也就是 为什么 3.3.2中的问题所在,但是为什么官方推荐要这样操作呢?继续往下看: - 图的最右边有一个
工具 devtools
,它是一个vue开发的浏览器插件,它可以记录每一次修改state的状态, 可以对数据操作进行跟踪,但是3.3.1案例跳过了走 actions和mutations ,直接操作 state 数据,这样就导致,devtools无法对state数据进行监控和跟踪,所以 官方建议是有道理的。这也就是对3.3.2的问题完美回答。
- devtools工具的安装在另一个博客上有写:vue学习:chrome 中 vuetools 开发插件 的下载、安装
- 虚线上面的是
vuex 的actions
,其实这一步是可以省略的,直接如下图走也行:
因为 mutations 是同步操作
数据的方法,而actions 是异步操作
数据的方法。如果要发请求则在actions 中进行操作,在调用mutations进行修改state数据。 vuex 的actions
连接图片最上面 是Backend API
就是后端的接口。所以 actions 是进行异步操作发送网络请求的地方。- 到此 这个图 就解说完啦。
四、对2.3.1案例使用vuex完美使用
1. 直接上代码
直接看代码截图吧,这样方便直接,代码都已上传到GitHub上,最上面前言中有GitHub地址。
先写 vuex
store/index.js
在写
App.vue
,调用mutations
中的方法,这里使用commit
方法。HelloVuex.vue
效果显示:
2. 总结
到目前为止,vuex的初始用就到这儿了
下一篇博客就是学习一下 vuex 的五个属性了,也是最为关键的。