为什么要用?vuex??
????????首先,需要清楚为什么要用?vuex?,当我们的应用遇到?**多个组件共享状态**?时
????????????????-?多层级父子组件状态传递会特别繁琐
????????????????-?非嵌套父子组件状态传递也会特别繁琐
vuex
????????Vuex?是一个专为?Vue.js?应用程序开发的?**状态管理模式**,类似?redux
这种状态管理模式包含:
????????这种模式遵循的是?单向数据流?模式
vuex?的工作流
安装?vuex
? ??????npm?i?vuex
????????????//?or
????????yarn?add?vuex
引入?vuex
? ??????通过?`import`?引入
? ? ? ? ? ????????? 通过?`import`?方式引入,需要手动安装(手动调用?`Vue.use(Vuex)`)
? ??????通过?\<script\>?引入
????????????????????通过?\<script\>?方式引入,vuex?会自动安装(也就是主动调用?`Vue.use(Vuex)`)
从?Store?开始
? ? ? ? `Store`? 就是仓库,我们前面提到的?`state`?就存储在?`store`?中,同时提交动作、修改状态的方法也都由?`store`?提供和管理
创建一个?Store
import?Vue?from?'vue'
import?Vuex?from?'vuex'
Vue.use(Vuex)
let?store?=?new?Vuex.Store({
????state:?{},
????getters:?{},
????mutations:?{},
????actions:?{}
})
????????????必须在?`Vue.use(Vuex)`?之后创建?`store`
核心概念
????????-?state
????????-?getters
????????-?actions
????????-?mutations
state
state?的创建
????????存储应用状态数据的对象,`state`?的值可以是一个对象,也可以是一个返回对象的函数,类似?vue?中组件的?`data`?,使用函数的方式
????????返回对象可以避免对象引用导致的副作用问题
????????通过?`store.state`?访问状态数据
?????????`state`?数据与组件?`data`?一样是被追踪的
在组件中使用?store
????问题: `state`?的更新并不会更新视图
解决
? ? ? ? 用computed(计算属性)
<template>
??<div?class="home">
????<h2>{{title}}</h2>
????<div>{{content}}</div>
??</div>
</template>
<script>
import?store?from?'@/stores'
export?default?{
??name:?'home',
??computed:?{
????title()?{
??????return?store.state.title
????},
????content()?{
??????return?store.state.content
????}
??}
}
</script>
store?配置
????????如果每个组件在使用?`store`?的时候都?`import`?会比较繁琐,这个时候,我们通过?vuex?提供的?`store`?选项把?`store`?对象注入
????????到?vue?的原型上
import?Vue?from?'vue'
import?App?from?'./App.vue'
import?router?from?'./router'
import?store?from?'@/stores'
Vue.config.productionTip?=?false
new?Vue({
??router,
??store,
??render:?h?=>?h(App)
}).$mount('#app')
????????????配置注入后,我们就可以在组件实例中使用?`this.$store`?来访问?`store`?对象了
使用辅助函数?`mapState`
????????当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用?`mapState`?
????????辅助函数帮助我们生成计算属性,让你少按几次键,通常我们把?`store`?的?`state`?通过?`mapState`?函数映射到组件的?`computed`?上
通过对象方式进行映射
????????场景:当组件中已有与?`store`?同名的数据名称
使用扩展运算符组合
????????通过对象扩展运算符,可以把?`mapState`?返回的?`state`?属性与组件已有计算属性进行融合
getters
????????有时候我们需要从?store?中的?state?中派生出一些状态,类似组件的?`data`?与?`computed`,`store`?也提供了一个?`getters`?对象来处理
????????派生数据
getters?函数
????????与组件属性一样,我们是通过定义一个函数的形式来返回派生数据的,`?getters`?函数接受两个参数
????????????????-?第一个参数:`state`?对象
????????????????-?第二个参数:`getters`?对象
通过属性访问
????????同样的,与组件计算属性一样,默认是通过属性的方式去访问?`getters`?中的数据的,这种方式与组件的计算属性一样,
????????也是会缓存 结果的
通过方法访问
????????我们还可以通过闭包函数的形式返回一个函数,来实现给?`getters`?函数传参,需要注意的是这种方式不支持结果缓存
使用辅助函数?`mapGetters`
????????与?`mapState`?函数类似,通常映射到组件的?`computed`?上
mutations(改变)
????????更改?Vuex?的?store?中的状态的唯一方法是提交?mutation(类似?redux?中的?action?+?reducer),Vuex?中的?mutation?非常类似于事件:
????????每个?mutation?都有一个字符串的?**事件类型?(type)**?和?一个?**回调函数?(handler)**
????????????????`mutation`?中的函数不要直接调用
commit(提交)
? ??????type
????????????????????要提交的?`mutation`?回调函数名称
? ??????payload
????????????????????载荷:提交的额外数据,任意格式
mutation?函数
????????`mutation`?中的函数被?`commit`?执行的时候,接收两个参数
????????????????-???第一个参数:`state`?对象
????????????????-???第二个参数:?`commit`?提交的?`payload`
????????在?`mutation`?函数中,我们就可以通过?`state`?对象进行状态数据的修改
使用辅助函数?`mapMutations`
????????`mapMutations`?函数的使用与?`mapState`?和?`mapGetters`?类似,但是其一般是把组件的?`methods`?映射
????????为?`store`?的?`mutations`?的?`commit`?调用
mutation?函数必须是同步的
????????`commit`?方法没有返回值
actions
????????`action`?中的函数与?`mutation`?中的函数类似,但是它主要用来进行异步任务的处理,然后通过提交?`mutation`?来修改?`state`
????????????????>?注意:`action`?中的函数不要直接修改?`state`
dispatch派发
????????`action`?任务需要通过?`dispatch`?方法来提交(派发),与?`commit`?类似
????????`dispatch`?方法有返回值,且一定返回一个?`promise`?对象
action?函数
????????`action`?中的函数执行的过程中也接受两个参数
????????????????-?第一个参数:`store`?对象
????????????????-?第二个参数:?`dispatch`?提交的?`payload`
使用辅助函数?`mapActions`
????????与?`mapMutations`?函数类似,把组件的?`methods`?映射为?`store`?的?`actions`?的?`dispatch`?调用
Module
????????这个更多的是基于一种代码组织结构上的辅助
????????????????https://vuex.vuejs.org/zh/guide/modules.html
????????????????https://vuex.vuejs.org/zh/guide/structure.html