Vu基础及其开发2_第1页
Vu基础及其开发2_第2页
Vu基础及其开发2_第3页
Vu基础及其开发2_第4页
Vu基础及其开发2_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第九章Vue状态管理学习目标熟悉Vue中的状态管理模式掌握Vuex的安装和基本使用掌握Vuex的核心概念的使用熟练使用状态管理的组合式API熟悉新的状态管理工具Pinia的使用在项目开发中,使用Vue进行组件化开发可以帮助开发人员快速构建动态的用户界面。对于简单页面中的组件,可以使用Vue本身提供的功能来管理组件的状态。然而,随着应用程序规模的增大,组件的数量和复杂度也会增加,导致组件的状态管理变得越来越复杂。为了解决这个问题,Vue提供了一些状态管理工具,如Vuex和Pinia,它们可以帮助开发人员更好地管理应用程序的状态,减少重复代码并提高代码质量。本章将重点介绍Vue的状态管理,包括传统的状态管理工具Vuex以及新的工具Pinia的使用。状态管理模式12Vuex的安装和使用3Vuex的核心概念4新的状态管理工具—Pinia5组合式API状态管理模式在Vue中,状态指的是应用程序中的数据。在项目中,大多数情况下,每个组件都有自己的数据状态。通常情况下,我们会使用data函数(OptionsAPI)或setup函数(CompositionAPI)来定义组件的数据状态。每个组件的数据状态都有其独立的作用域,这意味着组件之间的状态是相互隔离的,不会相互影响。在某些情况下,一个组件的状态可能需要被多个组件使用和修改。这些组件可能是跨层级的(父子组件)或者同层级的(兄弟组件)。如果组件之间的数据交互非常频繁,且涉及到的组件数量较多,这时候使用状态管理工具就非常有必要了。下面以一个经典的计数案例来看下状态管理的使用。首先,使用VueCLI或Vite创建一个Vue项目,然后在项目的“components”目录下创建一个“Counter.vue”。状态管理模式

上述代码中,Counter.vue中定义了一个count的状态,并在按钮的点击事件中触发了一个increment的操作来修改count状态的值。然后我们将Counter.vue组件注册到App.vue中,运行项目,通过点击按钮可以查看到count进行了递增。

在上述案例中,Vue实现了状态的自管理,在Vue的状态自管理中主要分为以下三部分组成:

状态(State),驱动应用的数据源,即data函数中定义的数据;视图(View),即显示的模板元素或组件,会以声明方式将状态映射到视图;操作(Actions),用户输入等操作导致视图上状态的改变;状态管理模式

从上图中可以看出,当View视图中响应了用户的Actions操作时,会导致State状态的变化,从而又更新了View视图,由此进行数据流的单向传递。当页面简单组件较少时,状态自管理会保持这种单向数据流操作,但是当多个组件共享状态的时候,不管是多个视图依赖同一个状态又或者是不同视图中的行为需要变更同一状态时都会导致单向数据流被破坏;状态管理模式

多个视图依赖同一个状态时。可能是组件嵌套的使用,也可能是平级的兄弟组件使用。对于嵌套组件的情况,我们可以使用props属性将状态作为参数传递给子组件,从而实现状态的共享和依赖。然而,对于平级组件之间的状态依赖,仅仅使用组件自身的状态管理是无法满足需求的。在这种情况下,就需要使用其他的解决方案,例如,Vue2.x的时候可以使用全局事件总线(EventBus),它通过创建Vue实例,通过$emit和$on方法来触发和监听事件,从而在组件之间传递参数。而在Vue3.x中,取消了Vue实例上的全局事件机制,需要借助于事件触发器插件(如mitt或tiny-emitter)来实现类似的功能。无论是全局事件总线还是事件触发器插件,它们在使用时需要在全局范围内进行维护。这可能会导致一些问题,如命名冲突等。

不同视图中的行为需要变更同一状态时。如果是嵌套组件,可以通过使用$emit触发事件,并将事件传递给父组件来实现状态的变更。如果嵌套的层次较多,需要一层一层地将事件传递给上层组件进行状态变更,这将会导致代码的维护性降低。

为了更好地实现状态管理,可以将组件的共享状态抽取出来,并使用全局单例模式进行集中式管理。在这种模式下,整个应用程序共享同一个状态对象实例。组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为。并通过强制规则维持视图和状态间的独立性,这样代码也将会变得更结构化并且更容易维护,这就是状态管理工具Vuex的基本实现思想。状态管理模式12Vuex的安装和使用3Vuex的核心概念4新的状态管理工具—Pinia5组合式APIVuex的安装和使用1.Vuex简介和使用场景Vuex是一个专门为Vue.js设计的状态管理模式。它允许开发者在Vue.js应用程序中集中管理所有组件的状态,而不必将状态存储在每个组件中,并以相应的规则保证状态以一种可预测的方式发生变化。在Vuex中,应用程序的状态存储在一个称为"store"的中央存储区域中。这个store对象包含了应用程序的所有状态,并且是唯一的数据源。通过Vuex的"mutations"(变化)和"actions"(操作),我们可以对存储在store中的状态进行更新和操作。"mutations"是一些同步函数,用于修改状态,而"actions"可以是异步的,用于处理复杂的业务逻辑或触发一系列的变化。Vuex还提供了一个“getter”函数,它允许开发者计算和派生状态,而无需重复编写计算逻辑。此外,Vuex还支持“模块”功能,以便将应用程序状态划分为多个模块,从而更好地组织和管理应用程序的状态。当然,并不是所有项目都需要使用Vuex进行状态管理。对于简单的小型项目,使用Vuex可能会增加项目的复杂性和冗余代码,不利于快速开发和维护。在这种情况下,简单的传参和事件模式就足以处理组件之间的通信和状态管理。而对于中大型的单页面应用程序,特别是当组件数量众多、状态复杂且需要在多个组件之间共享时,使用Vuex进行状态管理将是一个明智的选择。

Vuex的安装和使用2.Vuex的安装在Vue.js应用程序中使用Vuex之前,需要先安装它。需要注意的是,安装Vuex时要考虑Vue的版本号,因为每个Vue.js版本都有与之兼容的Vuex版本。如果使用的是Vue.js2.x版本,建议安装Vuex2.x,因为它具有更好的向后兼容性,但也可以选择Vuex3.x。对于Vue.js3.x版本,应该使用Vuex4.x或更高版本。在本章节中,我们将使用Vuex4.x版本。Vuex的安装方式分为以下三种方式:直接下载/CDN引用

对于基于HTML页面的Vue项目,可以通过两种方式引入Vue:使用CDN链接或指定本地下载的Vue.js文件。Vue官方推荐使用U提供的基于npm的CDN链接,该CDN链接可以始终指向npm上发布的最新版本,它也支持在CND链接上添加版本号引入指定的Vuex版本。需要注意的是,Vuex的引入一定要在Vue之后,因为Vuex是依赖于Vue的。创建项目的时候添加

如果使用了“vuecreate”命令或vueui界面创建项目,可以在选择预设模板时手动添加"Vuex"依赖。这样,在项目初始化过程中,VueCLI将会安装并配置Vuex。

Vuex的安装和使用npm或yarn安装

如果已经通过VueCLI或Vite创建了项目,可以使用npm或yarn安装Vuex依赖。执行如下指令:

或者

安装成功之后,在项目的package.json文件中的“dependencies”选项中就可以看到Vuex的依赖信息。npminstallvuex@next--saveyarnaddvuex@next--saveVuex的安装和使用3.Vuex的基本使用之前提到了,在Vuex中,所有的状态都被存储在中央存储库(store)中。组件可以通过获取store对象来获取存储的状态。通过mutations,可以对状态进行变化,而使用actions则可以执行一些异步操作。如果想要像在data函数中一样对状态进行计算,可以定义"getter"。下面还是以计数器为例,来看一下Vuex的实现方式。步骤如下:首先,在src下创建一个store.js文件。Vuex的安装和使用上述代码中,使用Vuex提供的createStore函数创建了一个中央存储库(store)实例。在store实例中,使用state来定义需要共享的状态,并使用mutations来定义修改状态的方法。在Vuex中,我们只能通过调用mutations或actions中定义的方法来改变共享状态,外部无法直接修改状态,这样可以更明确地追踪状态的变化。最后,通过exportdefault将store实例导出,以便外部可以访问它。在main.js文件中导入store实例并将其添加到Vue中。Vuex的安装和使用在components目录下创建Counter2.vue和Counter3.vue组件,并且让Counter.vue组件从store中获取和修改count状态。在上述代码中,在组件中使用this.$store可以获取到Vuex实例对象,可以使用this.$store.state在组件中获取state数据。而对于mutations中的变化方法,需要使用this.$mit的方式进行调用。Vuex的安装和使用④最后,将Counter2.vue和Counter3.vue组件引入到App.vue中,然后运行项目。在浏览器页面中,会看到当在Counter2组件中点击按钮修改count状态后,Counter3组件中的状态也会相应改变。如图所示。状态管理模式12Vuex的安装和使用3Vuex的核心概念4新的状态管理工具—Pinia5组合式APIVuex的核心概念想要更详细地了解Vuex的使用,需要从其核心概念开始。Vuex的核心概念包括state、mutation、action、getter和module。Vuex工作流程图,如图所示。

从图中可以看到,一旦创建了Vuexstore实例,该实例包含了state、mutations、actions等配置属性。通过调用commit方法来触发mutations对state进行变化,一旦state发生变化,Vue组件将重新渲染以反映最新的状态。除了mutations,Vue组件还可以通过dispatch方法调用actions执行操作。Vuex的核心概念1.StateVuex是基于全局单例模式实现的,其中的单例指的就是State状态对象。State作为应用程序的状态存储在Vuexstore中,它是一个单一的状态树,也被称为"唯一数据源"。这意味着我们可以将整个应用程序的状态存储在一个store对象中,并通过在根组件中使用app.use函数进行"注入",使得所有的子组件都能够通过this.$store来访问状态。为了更好的追踪状态的变化,State应该被视为只读状态,不能直接修改它。要修改State的值,应该通过提交(mutations)或触发(actions)来进行变更。这种限制确保了状态的变化是可追踪和可控的,也更符合Vuex的设计原则。在组件中,可以通过this.$store.state直接访问Vuexstore实例中的状态,并且这种访问方式会确保获取到的state状态具有响应式能力。为了在组件中更简便地使用Vuex的状态,通常会将状态的获取逻辑放在计算属性中,并将计算属性返回状态值。计算属性会自动依赖于使用到的状态,因此当相关状态发生变化时,计算属性会重新计算并保持响应式。这样可以方便地在模板中使用计算属性,而不需要手动监听状态的变化。Vuex的核心概念如果一个组件中需要获取很多的状态,使用computed的方式需要声明多个计算属性,这样会显得冗余和重复。为了解决这个问题,Vuex提供了mapState辅助函数来简化状态的获取。mapState函数接收一个数组或对象作为参数,并返回一个对象用于将state映射到组件的计算属性中。Vuex的核心概念上述代码中,在mapState的对象形式中,可以声明多个要使用的状态,并通过函数参数state来获取对应的状态值。如果计算属性的名称和状态的名称一致,可以简化为一个字符串数组的形式。Vuex的核心概念如果组件内部也需要定义计算属性,可以使用ES6提供的展开运算符对mapState函数返回的对象进行解构赋值。需要注意的是,尽管Vuex非常适合进行状态管理,但并不是所有在组件中使用的状态都应该放到State中。State中的状态适合多组件共享的状态,而组件内部使用的状态应该定义为组件的局部状态。这样可以使组件之间的状态更加清晰、独立,并且可以提高代码的可维护性。Vuex的核心概念2.Mutation在Vuex中,Mutation用于修改Store中的状态。Mutation是VuexStore中的唯一可修改状态的地方,它们类似于事件:每个Mutation都有一个字符串类型和一个处理函数,在处理函数中接受的第一个参数就是state,它可以用来修改状态。如之前案例中store.js中的定义的代码所示。在Vuex中,Mutation中定义的处理函数不能直接调用,而是需要使用store实例提供的commit方法来触发(或提交)Mutation。Mutation可以看作是一种注册的事件处理函数。通过在Mutation中定义处理函数,我们可以指定在何时、如何修改状态。这些处理函数是同步执行的,用于变更状态。比如,Counter2.vue中通过点击按钮触发事件,然后通过“this.$mit('increment')”触发Mutation从而修改了count的状态。Vuex的核心概念在提交Mutation时,可以通过传递参数(PayLoad载荷)到Mutation的处理函数中,以便进行相应的处理,这样使状态的修改更加灵活。在定义Mutation的处理函数时,可以将第二个参数作为载荷值或载荷对象。载荷可以是任何类型的值,通常情况下会使用对象来传递多个参数或复杂的数据。Vuex的核心概念提交mutation也可以直接使用包含type属性的对象,整个对象都作为载荷传给mutation函数,type属性值就是要触发的mutations事件。在Vuex中,可以使用常量来代替Mutation中处理函数的名称。这种做法可以将所有的处理函数名封装起来,使整个应用中包含的所有Mutation一目了然。Vuex的核心概念为了减少在组件中多次使用this.$mit来提交Mutation的冗余代码,Vuex提供了mapMutations辅助函数,可以帮助开发者将组件中的方法映射为mit调用。在Vuex中,Mutation中的处理函数应该是同步的操作,也就是说,它们应该立即修改状态,而不是异步地修改状态。这是因为Vuex需要能够准确地跟踪状态的变化,并在必要的时候执行相关的操作。例如,DevTools的时间旅行调试功能。这些工具依赖于能够捕捉到Mutation的前一状态和后一状态的快照,从而能够回溯和追踪状态的变化。如果在Mutation中执行异步任务,例如调用API请求或者定时器等操作,那么状态的改变将变得不可预测,因为异步任务的完成时间无法确定。这会导致DevTools无法准确地追踪状态的变化,从而影响调试和开发过程。Vuex的核心概念3.ActionAction类似于Mutation,不同的是Action可以用于处理异步操作或包含复杂逻辑的操作。Action不会直接修改状态,而是通过触发Mutation来间接地修改Store中的状态。这样可以确保状态的变化是可追踪的,并且保持了单向数据流的特性。下面我们来看一个异步操作状态改变的案例,如下所示。

在代码中,actions中处理函数跟mutations中定义类似。在actions中,处理函数的第一个参数是当前的store实例对象,可以通过该参数调用store的各种方法,包括提交mutation的commit方法,并且可以进行异步的操作。在组件中,可以通过store.dispatch方法来分发一个action。Vuex的核心概念在Vuex中,可以通过组合多个action来处理分步骤的业务逻辑。当一个action被触发时,它可以返回一个Promise对象,表示该处理函数的结果。在这种情况下,可以使用store.dispatch来处理这个Promise对象,并且store.dispatch本身也会返回一个Promise对象,使得开发者可以连续地分发多个action。Vuex的核心概念Vuex的核心概念如果使用ES6新特性async/await方式执行一些组合Action的异步操作,代码会更加的简洁易懂。Vuex的核心概念如果在组件中需要频繁地分发多个Action,为了简化代码,Vuex提供了mapActions辅助函数,可以将组件的methods映射为store.dispatch调用。Vuex的核心概念4.Getter在Vuex中,Getter用于从Store中获取派生状态,通过对现有状态进行计算而得到值。例如,对数组进行过滤,字符串验证等处理。Getter的返回值会根据依赖的状态发生变化而重新计算,从而触发相应的重新渲染。需要注意的是,从Vue3.0开始,Getter的结果不再像计算属性一样被缓存,每次访问Getter都会重新计算其值。Getter的处理函数接收state作为第一个参数,可以使用state对象对状态进行计算。此外,Getter的处理函数还可以接收其他Getter对象作为第二个参数,这样可以在其他Getter的基础上进行进一步的计算。Getter不会直接改变Store中的状态值,而是类似于组件中的计算属性,返回一个计算结果。可以在任何组件中使用this.$store.getters来访问Getter的计算结果。Vuex的核心概念接下来,我们在之前的案例的基础上,添加一个求count平方值的操作。Vuex的核心概念可以通过传递参数给Getter的处理函数来获取不同的计算结果。为了实现这个功能,Getter的处理函数需要返回一个函数,而不是直接返回计算结果。Vuex的核心概念当组件需要使用多个Getter时,可以使用mapGetters辅助函数来简化代码。mapGetters将store中的getter映射到组件的局部计算属性,使得在组件中可以直接访问这些getter,而无需手动编写计算属性。Vuex的核心概念5.Module如果项目中共享的状态比较少,我们只需要把所有的状态都定义在store.js中。但是在复杂的大型应用中,如果将所有的状态都集中到一个单一的store对象中,会导致store对象变得臃肿难以维护。为了解决这个问题,Vuex允许将Store拆分为多个模块(Module),每个模块可以拥有自己的state、Mutations、Actions和Getters,甚至是嵌套子模块(从上至下进行同样方式的分割)。这样可以使得应用程序的代码更加清晰、结构更加模块化。下面以一个简单的示例,展示如何在Vuex中使用模块分割。我们在store.js中分别创建counterModule、counter2Module两个对象,然后在创建store实例对象的时候为其配置modules选项。Vuex的核心概念5.Module如果项目中共享的状态比较少,我们只需要把所有的状态都定义在store.js中。但是在复杂的大型应用中,如果将所有的状态都集中到一个单一的store对象中,会导致store对象变得臃肿难以维护。为了解决这个问题,Vuex允许将Store拆分为多个模块(Module),每个模块可以拥有自己的state、Mutations、Actions和Getters,甚至是嵌套子模块(从上至下进行同样方式的分割)。这样可以使得应用程序的代码更加清晰、结构更加模块化。下面以一个简单的示例,展示如何在Vuex中使用模块分割。我们在store.js中分别创建counterModule、counter2Module两个对象,然后在创建store实例对象的时候为其配置modules选项。Vuex的核心概念

上述代码中,counterModule和counter2Module为定义的两个不同的module,并且分别用counter和counter2进行区分。在模块内部定义的state是局部状态,它们不会直接指向其他模块或根节点的状态。如果组件需要访问不同模块的状态,可以在访问状态时使用模块名称来进行访问。Vuex的核心概念

分析上面的代码发现,通过默认模块分割,可以将不同模块的状态封装和独立起来,但是对于Action、Mutation和Getter,默认情况下它们是注册在全局命名空间的。这意味着多个模块可以对同一个Action或Mutation作出响应,且Getter也是全局共享的。虽然Getter在全局命名空间下注册,但不建议在不同的、无命名空间的模块中定义两个相同的Getter,因为这可能会导致命名冲突和程序错误。Vuex的核心概念

如果希望每个模块内部定义的Getter、Action及Mutation也可以实现封装和复用,建议使用命名空间,可以通过在模块配置中设置“namespaced:true”来为模块启用命名空间。启用命名空间后,Getter、Action和Mutation都需要在模块中进行调用时指定命名空间。

对于具有命名空间的模块,访问方式确实会有所变化。在使用具有命名空间的Getter、Action和Mutation时,需要指定属于哪个命名空间。如右图所示。Vuex的核心概念

Vuex支持在store实例创建之后动态注册新的模块。可以使用store.registerModule(moduleName)方法进行注册。如果要注册的模块是嵌套模块,可以通过传递一个数组来指定嵌套路径。动态注册的模块,可以使用store.unregisterModule(moduleName)卸载动态模块。Vuex的核心概念在大型项目中,Vuex的项目结构一般推荐是下面这样的,如图所示。

在上面图中,可以看到大型项目中推荐把公用的、根级别的元素封装到统一的js文件中,如store目录下的index.js、actions.js、mutations.js,而对于模块独有的状态则分别封装到modules目录下的单独js文件中,然后使用export的方式暴露即可。状态管理模式12Vuex的安装和使用3Vuex的核心概念4新的状态管理工具—Pinia5组合式API组合式APIVuex提供了组合式的API,使得在组件的setup函数中可以轻松地使用Vuex。通过调用useStore函数可以获取一个Vuexstore的实例,类似于选项式API中的this.$store。使用store实例,可以访问到state、mutation和action等。状态管理模式12Vuex的安装和使用3Vuex的核心概念4新的状态管理工具—Pinia5组合式API新的状态管理工具—PiniaPinia读音为/pi:njʌ/,中文谐音“皮尼亚”。它是一个完全基于Vue3的响应式系统(兼容Vue2)设计的一个轻量级、新一代的状态管理工具。Pinia是Vuex下一个版本的迭代,Vuex从Vuex4后将不在提供升级维护,Vue作者也推荐将Pinia作为新项目的状态管理工具。与Vuex相比,Pinia不仅提供了一个更简单的API,也提供了符合组合式风格的API。最重要的是,搭配TypeScript一起使用时,有非常可靠的类型推断支持。Pinia的主要特点如下:基于Vue3响应式系统类型安全:Pinia支持TypeScript,可以为状态、Getter和动作提供类型定义,以提高代码的可读性和可维护性。基于类的API:Pinia使用基于类的API来定义Store、状态、Getter和Action,这使得代码更加结构化和易于理解。高效的代码拆分:Pinia支持模块化的Store,可以轻松地将Store拆分成多个模块,从而提高代码的可读性和可维护性。插件机制:Pinia支持插件机制,可以轻松地扩展其功能。例如,可以使用插件来支持异步动作、数据缓存等。新的状态管理工具—PiniaDevtools支持:支持追踪actions的时间线,在组件中展示它们所用到的Store;热更新:可以不必重载页面即可修改Store,也可以在开发时可保持当前的State;轻量级:相对于Vuex,Pinia是一个轻量级的状态管理库,体积小、性能高,适用于小型到中型应用程序。支持服务端渲Pinia与Vuex在核心概念上有些许差异,Pi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论