(一) Vuex
概述
1.组件之间共享数据的方式
父向子传值:v-bind
属性绑定
子向父传值:v-on
事件绑定
兄弟组件之间共享数据: EventBus
$on
接收数据的那个组件$emit
发送数据的那个组件
之前共享数据,是通过以上方式
以上方式,只适用于小范围内传递数据
2.Vuex
Vuex
是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
- 没有
vuex
时:A向B传递数据,需要一一传递,非常麻烦 - 有
vuex
时,A直接将要共享的数据,存储到Store
中,然后B直接从Store
中获取即可,非常简单。
3.使用 Vuex
统一管理状态的好处
① 能够在vuex
中集中管理共享的数据,易于开发和后期维护
② 能够高效地实现组件之间的数据共享,提高开发效率
③ 存储在vuex
中的数据都是响应式的,能够实时保持数据与页面的同步
Vuex
更适合用于传递数据,包括大范围传递
4.哪些数据适合存储到Vuex
中
一般情况下,只有组件之间共享的数据,才有必要存储到 vuex
中;
对于组件中的私有数据,依旧存储在组件 自身的 data
中即可。
(二) Vuex
的基本使用
1.Vuex
的使用步骤
第一步:安装 vuex
依赖包
npm install vuex --save
第二步:导入vuex
包
import Vuex from 'vuex' Vue.use(Vuex)
第三步:创建 store
对象
const store = new Vuex.Store({
// state 中存放的就是全局共享的数据
state: {
count:0}
})
第四步:将store
对象挂载到 vue
实例中
new Vue({
el: '#app',
render: h => h(app),
router,
// 将创建的共享数据对象,挂载到 Vue 实例中
// 所有的组件,就可以直接从 store 中获取全局的数据了
store
})
2.使用图形化界面创建Vuex
项目步骤
第一步:打开终端 输入vue ui
第二步:选择目录
第三步:创建项目
第四步:选择手动配置
第五步:选择依赖
第六步:eslint
配置
第七步:不保存预设
第八步:创建成功之后,默认有src/store/index.js
文件
第九步:main.js
文件
3. 初始化计数器项目的基本结构
第一步:运行项目 在vue ui
中——任务——serve
——运行——编译成功后——点击启动app
第二步:默认界面
第三步:src/App.vue
界面修改,删除之前的所有内容,修改如下:
<template>
<div>Hello World</div>
</template>
<script>
export default {
}
</script>
第四步:效果
第五步:删除HelloWorld
第六步:减法界面:components/Subtraction.vue
<template>
<div>
<h3>当前最新的count值为:</h3>
<button>-1</button>
</div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
第七步:加法界面:components/Addition.vue
<template>
<div>
<h3>当前最新的count值为:</h3>
<button>+1</button>
</div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
第八步:src/App.vue
app界面导入俩界面:
<template>
<div>
<my-addition></my-addition>
<h3>------------------</h3>
<my-subtraction></my-subtraction>
</div>
</template>
<script>
import Addition from './components/Addition'
import Subtraction from './components/Subtraction'
export default {
data () {
return {
}
},
components:{
'my-addition':Addition,
'my-subtraction':Subtraction
}
}
</script>
第九步:效果
第十步:配置格式的语法处理:末尾分号,单引号(根目录新建.prettierrc
)
{
"semi":false,
"singleQuote": true
}
第十一步:提交本地仓库
(三) Vuex
的核心概念
1.核心概念概述
Vuex
中的主要核心概念如下:
State
Mutation
Action
Getter
2.State
— 组件访问State
中数据的第一种方式
State
提供唯一的公共数据源,所有共享的数据都要统一放到 Store
的 State
中进行存储。
//创建store数据源,提供唯一公共数据
const store = new Vuex.Store ({
state:{
count:0
}
})
组件访问State中数据的第一种方式:
this.$store.state.全局数据名称
- 在
vue
界面中访问count:this.$store.state.count
(this可以省略)
定义并访问全局共享的数据——第一种方式
第一步:定义共享数据count
——src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0
},
mutations: {
},
actions: {
},
getters: {
}
})
第二步:访问count
——components/Addition.vue
<template>
<div>
<h3>当前最新的count值为:{
{$store.state.count}}</h3>
<button>-1</button>
</div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
- 在
template
中访问vue
实例中的内容时,this
可以省略 - 完整写法:
{ {this.$store.state.count}}
第三步:效果
3. State
—组件访问state
中数据的第二种方式
组件访问State
中数据的第二种方式
// 1. 从 vuex 中按需导入 mapState 函数
import {
mapState } from 'vuex'
通过刚才导入的mapState
函数,将当前组件需要的全局数据,映射为当前组件的computed
计算属性:
// 2. 将全局数据,映射为当前组件的计算属性
computed: {
...mapState(['count'])
}
mapState
是固定写法
-
可以理解为:
mapState
是state
数据映射的函数,通过mapState
可以获取state
中的数据 -
mapState(['state数据1','state数据2'])
,将想要获取的state
数据,作为参数传递给mapState
-
例如:
mapState(['count'])
,获取到的就是count
数据对应的一个对象{count:f}
-
打印
mapState(['count'])
,结果如下 -
这个
count
是一个function
,这个方法会将count
的真实数据返回 -
我们只需要对
mapState(['count'])
进行展开…运算之后,就可以获取到count
最终结果:
computed:{
count(){
return this.$store.state.count;
}
}
注意:因为count
是一个提供数据的函数,所以state
里的属性需要映射到computed
中,变成一个计算属性
定义并访问全局共享的数据——第二种方式
第一步:减法component/Suntraction.vue
<template>
<div>
<h3>当前最新的count值为:{
{count}}</h3>
<button>-1</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data () {
return {
}
},
computed:{
...mapState(['count'])
}
}
</script>
- 导入
mapState
之后,就可以使用第二种用法:可以将store
共享数据,映射为计算属性
第二步:效果
分析
4. Mutation
——触发mutation
的第一种方式
4.1错误演示+1操作
第一步:在 components/Addition.vue
中写入以下代码
<template>
<div>
<h3>当前最新的count值为:{
{$store.state.count}}</h3>
<button @click ="benHandler1">+1</button>
</div>
</template>
<script>
export default {
data () {
return {
}
},
methods:{
benHandler1() {
this.$store.state.count++
}
}
}
</script>
第二步:效果:可以成功,并且没有报错
- 可以成功,并且没有报错
- 但是这里我们不能这样处理,需要通过
Mutation
来修改store
的值
4.2 Mutation
的基本使用
Mutation
用于变更 Store
中 的数据。
① 只能通过 mutation
变更 Store
数据,不可以直接操作 Store
中的数据。
② 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
// 定义 Mutation
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
add(state) {
// 第一个形参永远是自身的state
// 变更状态
state.count++
}
}
})
// 触发mutation
methods: {
handle1() {
// 触发 mutations 的第一种方式
this.$store.commit('add')
}
}
commit
的内部逻辑
//commit的内部逻辑
function commit(mutationFn){
mutationFn(this.$store.state) // add(this.$store.state)
}
//调用代码
this.$store.commit('add');
//自己调用
this.$store.mutations.add(this.$store.state)
this.$store.mutations.add1(this.$store.state)
为啥只能通过mutation
来操作store
的数据呢?
-
为了统一管理,可以将修改
store
值的操作,统一在一起,可以方便监控数据的变化 -
比如:在
Addition
和Subtracion
以及其他很多界面,都是直接修改count
的值,那么后期发现count
的值有问题,那么我们就需要找很多文件,一个一个文件排查才可能找出问题,不方便监控数据的变化。
// components/Addition.vue
<template>
<div>
<h3>当前最新的count值为:{
{$store.state.count}}</h3>
<button @click ="benHandler1">+1</button>
</div>
</template>
<script>
export default {
data () {
return {
}
},
methods:{
benHandler1() {
this.$store.state.count++
}
}
}
</script>
4.3 Mutation
的基本使用
第一步:在src/store/index.js
—mutation
中定义add
方法,修改count
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0
},
mutations: {
add (state) {
state.count++
}
},
actions: {
},
getters: {
}
})
- 这样的话,所有的
count
修改的逻辑,都定义在mutations
中,以后想要知道哪里的逻辑修改了count
,就方便找了
第二步:在components/Addition.vue
中触发add
方法
<template>
<div>
<h3>当前最新的count值为:{
{$store.state.count}}</h3>
<button @click ="benHandler1">+1</button>
</div>
</template>
<script>
export default {
data () {
return {
}
},
methods:{
benHandler1() {
this.$store.commit('add')
}
}
}
</script>
commit
就是用于调用mutation
中的方法
第三步:效果
4.4Mutation
–在触发mutation
的时候携带参数
可以在触发 mutations
时传递参数:
// 定义Mutation
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
addN(state, step) {
// 变更状态
state.count += step
}
}
})
// 触发mutation
methods: {
handle2() {
// 在调用 commit 函数,
// 触发 mutations 时携带参数
this.$store.commit('addN', 3)
}
}
定义方法时:
- 第一个参数是固定接收
state
对象,参数名可以改,但是一般都是state
- 为啥第一个参数固定接收
state
对象,因为mutations
方法就是用于修改state
中的数据的, - 所以需要有
state
对象才能修改
- 为啥第一个参数固定接收
- 第二个参数
step
(自定义),就是我们在调用时传递的第一个参数
commit
:调用方法时
- 第一个参数:调用的方法名
- 第二个参数:给调用的方法传递的第一个参数值
4.5案例
第一步:在src/store/index.js
中定义带参数的mutations
方法
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)