Vue全家桶 Vuex的详细介绍_vuex4

totalAge(state) {
  return state.users.reduce((preValue, item) => {
    return preValue + item
  }, 0)
}

}
})


* **拿到结果进行展示**



{{ $store.getters.doubleCounter }}

{{ $store.getters.totalAge }}


**getters可以接收第二个参数getters**



> 
> 例如返回一个name并且拼接上users的年龄总和
> 
> 
> 



const store = createStore({
state: () => ({
name: “lin yj”,
counter: 100,
users: [
{id: 111, name: “chenyq”, age: 19},
{id: 112, name: “kaisa”, age: 20},
{id: 113, name: “vn”, age: 21}
]
}),
// getters对应一个对象
getters: {
// 1.将counter的两倍返回
doubleCounter(state) {
return state.counter * 2
},
// 2.将users中的年龄总和返回
totalAge(state) {
return state.users.reduce((preValue, item) => {
return preValue + item.age
}, 0)
},
// 3.name并且拼接上年龄总和
message(state, getters) {
// 由于年龄前面已经计算过一次了, 我们无需重新计算, 通过参数getters可以拿到
return ${state.name}: ${getters.totalAge}
}
}
})


* **拿到结果进行展示**




---


**getters的返回函数**



> 
> getters中的函数本身,可以返回一个函数,那么在使用的地方相当于可以调用这个函数
> 
> 
> 例如上面代码中在getters中实现一个根据id返回用户信息的函数
> 
> 
> 



const store = createStore({
// state函数要求返回一个对象
state: () => ({
name: “lin yj”,
counter: 100,
users: [
{id: 111, name: “chenyq”, age: 19},
{id: 112, name: “kaisa”, age: 20},
{id: 113, name: “vn”, age: 21}
]
}),
// getters对应一个对象
getters: {
getUserById(state) {
// 返回一个函数
return function(id) {
const user = state.users.find(item => item.id === id)
return user
}
}
}
})


* **在使用的地方可以调用getUserById函数**



{{ $store.getters.getUserById(111) }}

{{ $store.getters.getUserById(112) }}

{{ $store.getters.getUserById(113) }}


#### 🍧getter辅助函数



> 
> 和state类似, getters也有一个辅助函数mapGetters
> 
> 
> 


**Options API中使用辅助函数: 方便获取多个getters**



> 
> 使用方法基本上和mapState相似, 大家看看就行, 不再过多介绍
> 
> 
> 



{{ message }}

{{ totalAge }}

{{ meMessage }}

{{ usersAge }}



> 
> **在setup中使用mapGetters就像使用mapState一样, 是非常繁琐的, 不推荐使用;**
> 
> 
> **使用的方法和mapState一样, 同样不再多说, 大家可以自行尝试**
> 
> 
> 


**和state一样, setup中不推荐使用mapGetters**



> 
> 使用computd单独获取每一个元素
> 
> 
> 



{{ message }}

{{ totalAge }}

{{ getUserById(111) }}


### 核心概念Mutation


#### 🧁Mutation基本使用


**更改 Vuex 的 store 中的状态的唯一方法是提交 mutation**:



> 
> 比如, 我们如果想要修改store中的state中的counter属性, 我们并不能直接通过`store.state.counter`修改
> 
> 
> 我们必须通过commit提交mutation, 在mutation中进行修改
> 
> 
> 



const store = createStore({
state: () => ({
counter: 100,
}),
// commit提交到mutations
mutations: {
increment(state) {
state.counter++
},
decrement(state) {
state.counter–
}
}
})



当前计数: {{ counter }}


#### 🧁Mutation携带数据


**很多时候我们在提交mutation的时候,会携带一些数据,这个时候我们可以使用参数**:



> 
> 例如修改state中的name属性时, 可以将修改的内容通过传递参数传出
> 
> 
> 



const store = createStore({
state: () => ({
name: “lin yj”,
}),
// commit提交到mutations
mutations: {
// payload接收传入的参数
changeName(state, payload) {
state.name = payload
}
}
})



{{ $store.state.name }}

{{ $store.state.age }}

{{ $store.state.height }}



> 
> **payload也可以传入为对象类型**
> 
> 
> 



const store = createStore({
state: () => ({
name: “lin yj”,
age: 18,
height: 1.88,name: “lin yj”,
}),
// commit提交到mutations
mutations: {
// payload接收对象类型
changeInfo(state, payload) {
state.name = payload.name
state.age = payload.age
state.height = payload.height
}
}
})



{{ $store.state.name }}

{{ $store.state.age }}

{{ $store.state.height }}


#### 🧁Mutation常量类型


**我们发现, commit提交和mutation中的名称是需要保持一致的, 由于这个名称又不会更改, 所在开发中, 我们通常会给这些名称定义一个常量, 并将它放到独立的js文件中去**


* **定义常量:mutation\_type.js**



export const CHANGE_INFO = “CHANGE_INFO”


* **使用常量定义mutation**



// 导入常量
import { CHANGE_INFO } from “./mutation_types”;

const store = createStore({
state: () => ({
name: “lin yj”,
age: 18,
height: 1.88,name: “lin yj”,
}),
mutations: {
// 使用常量定义mutation
[CHANGE_INFO](state, payload) {
state.name = payload.name
state.age = payload.age
state.height = payload.height
}
}
})


**使用常量提交mutation**



// 导入常量
import { CHANGE_INFO } from “./store/mutation_types”

function changeInfo() {
// 参数传入一个对象
store.commit([CHANGE_INFO], {
name: “王老五”,
age: 20,
height: 1.58
})
}




---


#### 🧁Mutation辅助函数


**我们也可以借助于辅助函数,帮助我们快速映射到对应的方法中**:


* **Options API中的使用**



当前计数: {{ counter }}

{{ $store.state.name }}

{{ $store.state.age }}

{{ $store.state.height }}


* **Setup中同样不推荐使用mapMutation**




---


#### 🧁mutation重要原则


**Mutation有一条重要的原则就是: mutation中必须是同步函数**



> 
> 这是因为devtool工具会记录mutation的日记;
> 
> 
> 每一条mutation被记录,devtools都需要捕捉到前一状态和后一状态的快照;
> 
> 
> 但是在mutation中执行异步操作,就无法追踪到数据的变化;
> 
> 
> 


**所以Vuex的重要原则中要求 mutation必须是同步函数;**


**但是如果我们希望在Vuex中发送网络请求的话需要如何操作呢?**



> 
> 有事时候我们确实想要在Vuex中发送网络请求, 比如发送网络请求得到的数据是一些状态, 我们没必要在组件中发送网络请求再放到store中, 我们可以直接在store中发送网络请求
> 
> 
> 那么遇到这种情况, 就是我们接下来要学习的Actions核心, Actions是专门处理异步操作的地方, 我们的异步代码都需要在Actions中处理
> 
> 
> 




---


### 核心概念Actions


#### 🍸Actions基本使用


**Action类似于Mutation,不同在于**:



> 
> Action提交的是Mutation,而不是直接变更状态;也就是说, Action中想要修改state的话, 也需要提交Mutation, 不允许直接修改
> 
> 
> Action可以包含任意异步操作, Mutation中只能进行同步操作;
> 
> 
> 



mutations: {
increment(state) {
state.counter++
}
},
actions: {
incrementAction(context) {
// action中修改state需要提交mutation
context.commit(“increment”)
}
}


**我们发现这里有一个非常重要的参数context**:



> 
> context是一个和store实例均有相同方法和属性的context对象;
> 
> 
> 所以我们可以从其中获取到commit方法来提交一个mutation,或者通过 `context.state` 和 `context.getters` 来获取 state 和 getters;
> 
> 
> 



actions: {
incrementAction(context) {
// 提交mutation
context.commit(“increment”)
// 获取state中的状态
context.state.name
// 获取getter中的数据
context.getters.doubleCounter
}
}


**相信大家很疑惑为什么它不是store对象呢?这个在下面讲核心概念Modules时再具体来说**


#### 🍸Actions分发操作


**Options中Action的分发**


**如何使用action呢?进行action的分发**:



> 
> 分发使用的是 store 上的`dispatch函数`;
> 
> 
> 



{{ counter }}


**同样的,它也可以携带我们的参数, 例如修改我们刚刚的Info**


* 定义Action



actions: {
// 接收参数payload提交到mutation
changeNameAction(context, payload) {
context.commit(“changeName”, payload)
}
}


* 携带参数分发



{{ name }}


**也可以以对象的形式进行分发**:


* 定义Action



actions: {
// 接收参数payload提交到mutation
changeInfoAction(context, payload) {
context.commit(CHANGE_INFO, payload)
}
}


* 分发时传递对象作为参数



{{ name }}

{{ age }}

{{ height }}


**setup函数中Action分发**




#### 🍸Actions辅助函数


**action也有对应的辅助函数**:



> 
> 对象类型的写法;
> 
> 
> 数组类型的写法;
> 
> 
> 


* **数组类型的写法**



{{ counter }}


* 对象类型的写法



{{ counter }}


**Setup中同样不推荐使用mapAction**




---


#### 🍸Actions异步操作


**Action 通常是异步的,那么如何知道 action 什么时候结束呢?**



> 
> 我们可以通过让action返回Promise,在Promise的then中来处理完成后的操作;
> 
> 
> 


**演示代码**:


* **将网络请求的数据请求到vuex中**



const store = createStore({
state: () => ({
// 1.用于存放网络请求的数据
banners: [],
recommends: []
}),
mutations: {
// 2.定义mutation用于修改state的banners和recommends
changeBanners(state, payload) {
state.banners = payload
},
changeRecommends(state, payload) {
state.recommends = payload
}
},
actions: {
// 3.定义发生网络请求的Action
fetchHomeMulitidataAction(context) {
// 发生网络请求
fetch(“http://123.207.32.32:8000/home/multidata”).then(res => {
return res.json()
}).then(data => {
// 修改state中banner的数据, 提交mutation
context.commit(“changeBanners”, data.data.banner.list)
// 修改state中recommends的数据, 提交mutation
context.commit(“changeRecommends”, data.data.recommend.list)
})
}
}
})


* **请求到数据后可以获取vuex中的数据进行展示**



  • {{ item.title }}

### 核心概念Module


#### 🥃module基本使用


**什么是Module?**



> 
> 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象,当应用变得非常复杂时,store 对象就有可能变得相当臃  
>  肿, 例如刚刚我们发送了一个网络请求存放Home的数据, 如果还有很多个组件需要在vuex中发送网络请求, 这个时候store对象就会越来越臃肿;
> 
> 
> 为了解决以上问题,Vuex 允许我们将 store `分割成模块`(module);
> 
> 
> 每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块;
> 
> 
> 


**演示代码**


* **将刚刚home组件请求的数据单独抽离到一个home.js文件中, js文件返回一个对象**



export default {
state: () => ({
// 网络请求的数据
banners: [],
recommends: []
}),
mutations: {
// 定义mutation用于修改state的状态
changeBanners(state, payload) {
state.banners = payload
},
changeRecommends(state, payload) {
state.recommends = payload
}
},
actions: {
fetchHomeMulitidataAction(context) {
fetch(“http://123.207.32.32:8000/home/multidata”).then(res => {
return res.json()
}).then(data => {
// 修改state中banner的数据, 提交mutation
context.commit(“changeBanners”, data.data.banner.list)
// 修改state中recommends的数据, 提交mutation
context.commit(“changeRecommends”, data.data.recommend.list)
})
}
}
}


* **再将抽离出去的模块导入store对象**



// 1.导入抽离出去的模块
import HomeModule from “…/module/home”

const store = createStore({
state: () => ({}),
getters: {},
mutations: {},
actions: {},
modules: {
//模块名: 模块对象
home: HomeModule
}
})


* **展示state状态时, 要从模块中获取; 而getter、mutation、action不需要, 因为他们默认会被合并到根模块中去, 一般情况下都可以直接获取**



  • {{item.title}}

**对于模块内部的 mutation 和 getter,接收参数的state或getters是模块的局部状态对象**


* **还可以接收第三个参数rootState, 通过rootSate可以拿到根模块中的状态对象**




---


#### 🥃module命名空间


**默认情况下,模块内部的getter、action和mutation仍然是注册在`全局的命名空间`中的**:



> 
> 这样使得多个模块能够对同一个 action 或 mutation 作出响应, 这并不是我们想要的结果, 导致在模块中我们取名需要非常小心避免重复;
> 
> 
> Getter 同样也默认注册在全局命名空间;
> 
> 
> 


**如果我们希望模块具有更高的封装度和复用性, 解决这个尴尬的问题**


**web浏览器中的javascript**

*   客户端javascript
*   在html里嵌入javascript
*   javascript程序的执行
*   兼容性和互用性
*   可访问性
*   安全性
*   客户端框架
*   **[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

![](https://img-blog.csdnimg.cn/img_convert/ed2c4f9602fb053965a21c047d1291e6.png)  

**window对象**

*   计时器

*   浏览器定位和导航

*   浏览历史

*   浏览器和屏幕信息

*   对话框

*   错误处理

*   作为window对象属性的文档元素

![](https://img-blog.csdnimg.cn/img_convert/81adbbfdefca6b401d7dc4e6acd9207d.png)
  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值