版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第五章Vue组件进阶学习目标掌握Vue组件的生命周期熟悉props进阶的使用熟悉异步组件的使用熟悉Vue的内置组件使用在上一章节中,我们已经学习了Vue组件的基础使用,并可以实现一些简单组件的定义。但是,在实际开发中,仅仅会定义简单的组件是远远不够的。对于复杂的页面场景,我们需要更加深入地了解组件。例如,如何在组件加载DOM的时候去请求服务端数据完成数据的动态渲染?再比如,当页面中加载的组件非常多,并且每个组件都需要加载数据进行渲染时,如果默认是同步加载组件,那么大量组件加载会导致加载资源变慢。这时,我们应该如何解决呢?通过本章的学习,开发者将更加深入地了解组件的原理和使用方法。只有这样,才能帮助开发者在日常开发中更加灵活地使用组件来开发项目应用。组件生命周期12Props进阶3异步组件4内置组件组件生命周期每个Vue组件实例,无论是根组件还是自定义组件,都会经历从创建到销毁的过程。在这个过程中,Vue执行了许多操作,如设置数据监听、编译模板、将实例挂载到DOM上,以及在数据改变时更新DOM等。这个过程被称为组件的生命周期。Vue在组件的生命周期中提供了一套回调函数,也称为生命周期钩子函数。这些回调函数可以让开发者在特定的阶段运行自己的代码,以方便处理特定的业务逻辑。图5-1中红线的部分都是Vue的生命周期钩子函数,下面我们就来详细介绍下生命周期钩子函数。组件生命周期组件生命周期1.beforeCreate在组件实例即将创建之前执行,beforeCreate函数会在实例初始化完成、props解析之后、data()和computed等选项处理之前立即调用。那意味着在beforeCreate函数中我们是无法获取到data数据的,也不能进行相关计算等操作的。
2.created在组件实例处理完所有与状态相关的选项后调用,即此时组件已经创建完成。当created被调用时,已经完成了响应式数据、计算属性、方法和侦听器。此时可以调用data()里面定义的数据、使用计算属性和侦听器以及调用methods声明的方法。但是这个阶段还没有创建DOM节点也没有进行数据的挂载,因此无法操作DOM,$el属性也无法使用($el属性是组件挂载后对应的DOM元素)。组件生命周期3.beforeMount在组件被挂载之前调用的钩子函数。当这个钩子被调用时,组件已经完成了其响应式状态的设置,但还没有创建DOM节点。它即将首次执行DOM渲染过程。4.mounted在组件被挂载之后调用。组件的挂载完成指的是其内部所有的同步子组件已经挂载了(不包含异步组件或<Suspense>树内的组件),并且其自身的DOM树已经创建完成并插入到了父容器中。5.beforeUpdate在组件即将因为一个响应式状态变更而更新其DOM树之前调用,即组件更新前执行。因为beforeUpdate是在更新DOM树前调用,所以在这个钩子中可以安全的更改数据的状态。组件生命周期6.updated在组件因为一个响应式状态变更而更新其DOM树之后调用,即组件更新后执行。updated会在组件的任意DOM更新后被调用,如果内部有子组件则父组件在子组件updated之后才会调用自己的updated函数。7.beforeUnmount当组件实例被卸载之前调用。当这个钩子被调用时,组件实例依然还保有全部的功能。8.unmounted当组件实例被卸载之后调用。在Vue中组件被卸载意味着其内所有子组件也被卸载,所有相关的响应式操作也已经停止。这个钩子函数的作用是允许开发者自己手动执行一些释放资源操作,如停止计时器、DOM事件监听器或者与服务器的连接等。组件生命周期除了上述的钩子函数外,Vue还针对一些特殊情况提供了钩子函数,这些钩子函数有:9.errorCaptured在捕获了后代组件的错误时调用。当前嵌套的后代组件中出现组件渲染、事件处理器、生命周期钩子、setup()函数、侦听器等错误时,都可能会调用errorCaptured钩子函数。利用这个特性可以在errorCaptured进行错误阻止(钩子返回false即可)或提示,可以避免一些后代组件无限循环渲染等问题。10.renderTracked该钩子函数仅开发模式下可用(调式),它在响应式依赖被组件的渲染追踪后调用。它会跟踪页面上所有响应式变量和方法的状态,只要有更新的情况,就会跟踪并生成一个event事件对象,并被调用触发。11.renderTriggered该钩子函数仅开发模式下可用(调式),它在响应式依赖被组件触发了重新渲染之后调用。12.activated和deactivated当使用<KeepAlive>缓存组件的时候,当组件从DOM中被移除时调用deactivated;当组件被插入到DOM中时调用activated。组件生命周期下面我们通过一个实例来感受下生命周期钩子函数的使用。组件生命周期上述代码中,我们在app根组件添加了一个<h1>的DOM模板进行渲染,并使用vm.title更新了title的数据状态。运行代码后,可以在浏览器的Console控制台中看到结果,如图所示。组件生命周期由图中可知,app根组件经历了beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、renderTracked、renderTriggered这几个钩子函数,因为app内并没有子组件,并且app根组件也在使用中,所以并没有经历errorCaptured、beforeUnmount和unmounted这三个钩子函数。组件生命周期我们可以在app中注册使用一个自定义的子组件,并故意制造一个未定义方法的调用错误。运行代码,发现errorCaptured钩子函数被调用,如图所示。组件生命周期下面,给子组件继续添加beforeUnmount和unmounted钩子函数。同时,在app中添加一个按钮,并通过按钮点击事件将子组件通过v-if进行卸载。组件生命周期运行代码,因为v-if是真渲染,如果条件不成立之前加载的组件则会进行卸载。通过v-if的特性,可以看到子组件执行了beforeUnmount和unmounted钩子函数,如图所示。组件生命周期需要注意的是,在Vue3中官方推荐使用setup()函数来代替beforeCreate和created钩子函数,并且可以通过在生命周期钩子前面加上“on”变成组合式API来访问组件的生命周期钩子。这些生命周期钩子组合API借助于setup()函数的特性,可以更好的实现逻辑的组合使用,对于组合式API我们会在后面Vue进阶章节中进行详细的介绍。组件生命周期12Props进阶3异步组件4内置组件Props进阶1.Props类型在第四章节中,我们已经学习了props的基本使用,它可以用于父组件和子组件之间传递数据。props被用来声明组件的属性,并在父组件使用该子组件时,可以通过props传递参数数据。props的期望值可以定义为字符串数组或对象,之前,我们将props的期望值定义为字符串数组形式,这意味着属性的值可以是任意类型。如果我们想要指定prop属性的类型,我们可以将props的期望值定义为对象。Props进阶如果属性的名称很长,应该使用camelCase(小驼峰命名法)。但是在组件使用时,通常会将属性的名称写成kebab-case(短横线连接命名法)形式。属性的类型可以为String、Number、Boolean、Array、Object、Date、Function、Symbol和自定义类或构造函数。当属性定义为Number、Boolean、Array或者Object,在使用常量或静态值的时候都需要使用v-bind才行,String类型的常量或静态值可以直接使用。Props进阶2.Props只读和计算属性组件中所有的props都遵循着单向绑定原则,props会因父组件的更新而变化,但是对于组件内部来说props是只读的,我们不能够在组件内部去修改props的值;否则props一旦修改就会修改父组件的状态,应用的数据流将很容易变得混乱而难以理解。我们尝试运行下面左图中的一段代码。运行代码后,可以看到Pops只读警告信息,如右图所示。Props进阶props虽然为只读,但是如果需要对传入的属性值做进一步的转换,那么可以通过computed计算属性来完成。Props进阶3.Props校验props使用了类型声明后,如果类型不对,那Vue会在浏览器的控制台中抛出警告信息,这是因为Vue组件会更细致地对props进行校验。除了类型的校验外,props还支持声明props的默认值、是否必须传递、参数为多类型值以及自定义类型校验函数等功能。Props进阶
代码中,属性中的type表示数据类型,default为属性的默认值(可以是工厂函数的返回值)。validator为自定义类型。如果校验失败,则会在浏览器控制台中抛出警告。Props进阶
在组件中,除了声明为required:true的属性外,其他属性都是可选的。对于未传入的属性(未设置default),除了Boolean类型外,其默认值均为undefined;对于Boolean类型的未传递属性,默认会转换为false;如果传递了Boolean类型的属性但是没有设置值,则会隐式地转化为true。Props进阶4.依赖注入通常情况下,当需要父组件传递数据给子组件时,我们会使用props。但是,在组件嵌套层级非常深的情况下,如果深层子组件想要使用一个祖先组件的数据,就需要逐层将props传递下去,如下图所示。这显然会带来很多麻烦,并且可能会影响中间层组件的使用,这一问题被称为“prop逐级透传”,我们需要尽量避免这种情况的发生。Props进阶
为了解决prop逐级透传的问题,Vue提供了依赖注入的概念。依赖注入指的是父组件作为依赖提供者,为所有后代组件提供依赖;任何后代组件都可以注入由父组件提供整条链路的依赖。这种方式避免了props传递过程中的层级间隔问题,使得组件之间的数据传递更加便捷。
依赖注入需要使用provide和inject两个选项配置来实现,父组件通过provide提供数据依赖,后代组件中可以通过inject注入进行使用。
有时候我们需要提供当前组件实例的状态作为依赖(例如使用父组件data()定义的数据属性),这时就需要以函数的形式使用provide,使用函数的形式,可以访问到`this`。
除了可以在组件内使用provide选项的方式作为依赖提供者外,也可以通过vide()方式为整个应用层面提供依赖。Props进阶
在后代组件中使用inject选项进行依赖注入时,期望值可以是字符串数组或对象。当inject为字符串数组时,直接在数组中声明要使用的provide的key即可;当inject为对象时,为了避免属性重名可以注入别名,也可以设置默认值。整个依赖注入过程非常灵活和方便。Props进阶
上述代码中,在根组件中嵌套了一个MyMenu组件,在MyMenu组件中又嵌套了一个MyLabel组件,并实现了局部组件的注册。运行上述代码,在浏览器中可以看到,MyLabel组件中已经获取到了app组件中的title数据,如图所示。Props进阶
需要注意的是,依赖注入的数据默认是无法响应式的。也就是说在之前的案例中,即使我们通过devtools工具或者vm.title修改了title的内容,子孙组件MyLabel中也不会被改变。为保证注入方和供给方之间的响应性链接,我们需要使用computed()函数提供一个计算属性。组件生命周期12Props进阶3异步组件4内置组件异步组件在大型项目中,需要加载的组件数量会非常大。如果在用户首次访问网站页面时就一次性加载所有组件,那么网站页面的加载速度将非常缓慢。为了提高首屏页面的加载效率,可以在只有需要某个组件时才去加载它,而不是一次性加载所有组件。这种需求可以通过使用异步组件来实现。Vue提供了defineAsyncComponent方法,可以将组件异步加载。该方法接受一个返回Promise对象的加载函数。Promise是ES6语法新增的类,可以优雅地实现异步任务的编程。关于Promise对象的使用,这里不再进行详细介绍,开发者可以自行搜索学习关于Promise的相关使用。在defineAsyncComponent方法中,需要在Promise的resolve()回调方法中返回定义的组件。当然,也可以使用Promise的reject()回调方法表明组件加载失败。异步组件的注册方式与普通组件相同,只是在注册时需要使用defineAsyncComponent方法返回的异步组件进行注册。异步组件异步组件
需要注意的是,无论是在Vue文件的单页面组件开发还是HTML文件开发中,使用defineAsyncComponent时都需要通过import引入。此外,对于.vue文件的开发,也可以使用ES模块动态导入的方式。这种动态导入使用import()方法,并会返回一个Promise对象。
异步操作不可避免地会涉及到加载和错误的状态,因此defineAsyncComponent()也支持定义更多的选项来处理这些状态constAsyncCustomCom=defineAsyncComponent(()=>import('vue组件路径'))组件生命周期12Props进阶3异步组件4内置组件内置组件Vue提供了一些内置组件,可以直接在模板中使用,无需注册。这些内置组件支持Tree-Shakeable,意味着仅在使用时才会包含在构建中,这有助于减小打包后的文件体积。Vue的内置组件有<Transition>、<TransitionGroup>、<KeepAlive>、<Teleport>和<Suspense>,其中<Transition>、<TransitionGroup>为动画相关组件,我们会在后面章节中进行介绍,<Suspense>为实验性的内置组件,因此本章节中主要介绍<KeepAlive>和<Teleport>的使用。内置组件1.<KeepAlive>使用<component:is="组件">可以实现多个组件之间的动态切换,但是这种方式会不断地创建和销毁组件实例,导致性能问题。当一个组件被替换掉销毁之后,之前的状态也会丢失,再次显示时会创建一个新的只带有初始状态的实例。在章节4.5中的tab选项卡中如果有个输入框,当输入了一些重要的信息并切换到别的tab选项卡再切换回来,就可以看到之前输入的内容就没有了,这样用户体验就不是很好。为了解决这个问题,可以使用内置组件<keep-alive>。它的作用是可以让其内部的多个组件间在动态切换时缓存被移除的组件实例,这样,即使在动态切换时被移除的组件也会被保存到内存中而不是销毁,从而保留已变化的所有状态。这样做可以提高页面性能并避免多次重新渲染。我们以章节4.5中的选项卡效果为例,向其中添加一个输入框来演示组件的效。内置组件运行上述代码后,当我们在tab1中的输入框输入内容后切换到其他选项卡,然后再切换回来时,发现内容依然存在。内置组件<keep-alive>默认是缓存所有的组件,为了满足更多的缓存场景,<keep-alive>提供了三个属性参数:include:根据组件的name选项进行匹配,可以是以英文逗号分隔的字符串、一个正则表达式,或是包含这两种类型的一个数组的匹配,只有组件有name选项并且被匹配到才会被缓存。exclude:跟include正好相反,name选项匹配到的不会被缓存。max:指定最大可以缓存的组件实例的数量。内置组件因为include和exclude的用法一样,这里以include为例来看下其匹配组件的用法。内置组件使用<keep-alive>缓存组件时,在“切走”和“切回”的两个过程中会经历activated和deactivated两个钩子函数,我们给tab1组件添加上这两个钩子函数。在使用多个选项卡切换时,会调用了组件的activated和deactivated钩子函数,如图所示。内置组件2.<Teleport><Teleport>内置组件被称为“传送门”,它可以将一个组件内部的部分模板“传送”到该组件的DOM结构外层的位置去。通俗的讲,我们希望做一个组件效果,而这个效果的DOM模板不希望放到使用它的组件的DOM结构内,甚至是不希望在APP的DOM结构内,但是又能够在使用到它的时候连接到这个D
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2023年全国统考数学一冲刺试卷(名师编写)
- 数学一历年真题(2025考研全国统考·带详细目录)
- 数学一冲刺试卷(2025考研全国统考·真题逐题精讲)
- 数学三冲刺试卷(2025考研全国统考·完整版)
- 2026年大学教育学(课程与教学论专题)试题及答案
- 深圳科目四考试题及答案
- 2026年高职思想政治教育(思想政治教育教学案例分析)试题及答案
- 立式铣床考试题及答案
- 听力填词考试题及答案
- 2026年大学机械设计与制造(机械制造工程)试题及答案
- 工行普惠产品培训
- 小学实验操作安全培训课件
- 专题03 代数式化简求值的四种考法 初中数学人教版(2024)七年级上册(原卷版)
- 仿真造景合同范本
- 制图员专业理论知识考试题库(含答案)
- GB/T 46585-2025建筑用绝热制品试件线性尺寸的测量
- 基坑作业安全培训内容课件
- DB3301∕T 0314-2020 城市道路养护规范
- 劳动课行李箱收纳课件
- 小小牙医体验活动方案
- 低纤维蛋白原血症输注护理查房
评论
0/150
提交评论