Vuex详细介绍

2022-12-22 0 523

1. 甚么是Vuex

Vuex 是两个专为 Vue.js 应用领域软件开发的状况区域化。这是官方网站的讲法,只不过很单纯:是两个升级版的data! 在白眉林应用领域中常有两个data表达式,里头就放置了现阶段网页的许多统计数据。比如说:

<template> <div> <p>{{num}}</p> </div> </template> <script> export default { data(){ return { num:99 } } } </script>

标识符中的data就相等于他们这儿叙述的Vuex。 假如他们的网页非常单纯,当心一千万千万别发火导入Vuex,他们采用Vuex原因在于工程项目非常繁杂后,有许多统计数据须要在父模块、子模块和孙模块之间传达,处置出来很繁杂,只好就须要Vuex这种两个能对这一小部分统计数据展开标准化管理工作的小东西。

2. 自上而下data要是,非要那么繁杂?

对我才刚提及的市场需求:处置大批的须要在模块间传达的统计数据,间接表述两个自上而下的data特性留存要是,比如说这种:this.$root.$data。为甚么还要搞两个那么繁杂的状况管理工作? 假如他们按照才刚所说的搞两个自上而下变量放置统计数据只不过也行,但是这种有两个问题,是统计数据改变后,不会留下变更过的记录,这种不利于调试。 所以他们稍微搞得繁杂一点。他们约定模块不能间接修改属于store实例的state,模块必须通过Mutation来改变state,也是说,模块里头应该执行分发(dispatch)事件通知store去改变。这种约定的好处是,他们能够记录所有store中发生的state改变,同时实现能做到记录变更、留存状况快照、历史回滚/时光旅行的先进的调试工具。

3. 先来两个简单的State

知道了个大概,那他们就实际操作一遍,感觉一下这个听出来很牛逼的小东西用出来到底怎么样。 他们采用vue-cli脚手架生成两个Vue工程项目,并且安装Vuex,最终的工程项目结构是这种的:

Vuex详细介绍

他们在components里头新建两个模块,然后加入以下标识符:

<p>{{ count }}</p> <div> <p> <button @click=“increment”>+</button> <button @click=“decrement”></button> </p> </div>methods:{ increment(){ }, decrement(){ }, },

接着新建两个vuex文件夹,里头新建两个store.js文件,并加入以下标识符:

import Vue from vue import Vuex from vuex Vue.use(Vuex) // 应用领域初始状况 const state = { count: 0, } // 创建 store 实例 export default new Vuex.Store({ state, })

然后他们在模块中就能采用他们的count变量了:

computed:{ count(){ return this.$store.state.count; }, }

他们表述两个计算特性,返回store中的count变量:

Vuex详细介绍

3. 计算特性?导入Getter

这儿他们能假想两个场景,他们的网页中现在显示的数字是0,假如他们的市场需求是这种的,网页中数字假如小于10,就显示为00。那他们能在才刚的模块中将计算特性返回的值修改成这种:

return this.$store.state.count > 9 ? this.$store.state.count : 0+this.$store.state.count;

就能了,但是假如他们有许多模块都采用了这个count的话,那他们在每两个采用这个变量的地方都须要写一遍这个判断,那为甚么不在取统计数据的时候就把统计数据整理成想要的样子呢?就和他们模块中的计算特性一样!为了达到目的,他们修改一下store.js:

import Vue from vue import Vuex from vuex import * as getters from ./getters //新增 Vue.use(Vuex) // 应用领域初始状况 const state = { count: 0, } // 创建 store 实例 export default new Vuex.Store({ state, getters //新增 })

然后他们新建两个getters.js文件:

export const countaddzero = state => { return state.count > 9 ? state.count : 0 + state.count; }

最后他们改一改模块中的计算特性:

return this.$store.getters.countaddzero;

留存后发现网页上的数字果然变成了00。

4. 试试修改State,导入Mutation

他们的本意是要做两个点击按钮数字能增加的两个小demo,现在把统计数据存到store是完成了。接下来说一下如何修改统计数据。 为了方便查看,他们先修改一下store.js这个文件:

import Vue from vue import Vuex from vuex import * as getters from ./getters Vue.use(Vuex) // 应用领域初始状况 const state = { count: 0, } // 表述所需的 mutations //新增 const mutations = { //新增 increment(state, val = 1) { //新增 state.count += val; //新增 }, //新增 decrement(state, val = 1) { //新增 state.count -= val; //新增 } //新增 } //新增 // 创建 store 实例 export default new Vuex.Store({ state, getters, mutations //新增 })

其中的val表示点击按钮每次须要增加(减少)多少。 有了mutations他们就能在模块中对store里头的state展开修改了,他们先处置一下模块中的点击事件,当点击加或者减按钮的时候才去修改store里头的值。他们修改一下模块的methods:

methods:{ increment(){ this.$store.commit(increment,2); //新增 }, decrement(){ this.$store.commit(decrement,2); //新增 }, },

其中的2是之前提及的每一次增加多少,也是前文的val。他们约定只能通过commit的方式修改store的变量,为甚么说是预定呢?手贱的我决定试试:

methods:{ increment(){ // this.$store.commit(increment,2); //修改 this.$store.state.count=1000; //新增 }, },

只不过这样也能修改store里头的值,但是这种就不能达到他们刚开始所说的目的了。 一条重要的原则是要记住mutation必须是同步表达式。因为他们不知道甚么时候回调表达式实际上被调用——实质上任何在回调表达式中展开的状况的改变都是不可追踪的。

5. 异步修改?导入Action

那假如他们就想异步的修改store的值呢?也是有办法的,这时候就须要他们的Action出场了: Action 类似于 mutation,不同在于:

Action 提交的是 mutation,而不是间接变更状况。

Action 能包含任意异步操作。

他们还是先改改标识符,他们新建两个actions.js:

export const incrementAsync = ({ commit }, val = 1) => { setTimeout(() => { commit(increment, val) }, 1000) } export const decrementAsync = ({ commit }, val = 1) => { setTimeout(() => { commit(decrement, val) }, 1000) }

这儿他们采用setTimeout模拟一下异步执行。接着修改他们的模块

<p>异步:<button @click=“increment2”>+</button> <button @click=“decrement2”></button> </p>

修改一下methods:

methods:{ increment2(){ this.$store.dispatch(incrementAsync,2); }, decrement2(){ this.$store.dispatch(decrementAsync,2); }, },

Action通过store.dispatch方法触发,乍一眼看上去感觉多此一举,他们间接分发mutation岂不更方便?实际上并非如此,还记得mutation必须同步执行这个限制么?Action 就不受约束!他们能在 action 内部执行异步操作。 最后修改一下store.js文件: 在顶部导入actions:import * as actions from ./action 然后在实例化的时候加入actions:

// 创建 store 实例 export default new Vuex.Store({ actions, //新增 getters, state, mutations })

这种就能实现异步修改store啦!

6. 不方便维护?导入Module

由于采用单一状况树,应用领域的所有状况会集中到两个比较大的对象。当应用领域变得非常繁杂时,store 对象就有可能变得相当臃肿。 为了解决以上问题,Vuex允许他们将store分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下展开同样方式的分割:

const moduleA = { state: { }, mutations: { }, actions: { }, getters: { } } const moduleB = { state: { }, mutations: { }, actions: { } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的状况store.state.b // -> moduleB 的状况

7. 一点点注意事项

当在严格模式中采用 Vuex 时,在属于 Vuex 的 state 上采用 v-model 会比较棘手:

<input v-model=“obj.message”>

假设这儿的 obj 是在计算特性中返回的两个属于Vuex store的对象,在用户输入时,v-model会试图间接修改obj.message。在严格模式中,由于这个修改不是在 mutation 表达式中执行的, 这儿会抛出两个错误。 也是说只不过双向统计数据绑定和vuex是会有一点冲突的,不过化解的方法也有: 第一种方法: 给 中绑定 value,然后侦听input或者change事件,在事件回调中调用 action:

<input :value=“message” @input=“updateMessage”>

也是不实用v-model。 第二种方法: 双向绑定的计算特性

<input v-model=“message”>computed: { message: { get () { return this.$store.state.obj.message }, set (value) { this.$store.commit(updateMessage, value) } } }

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务