《Vue 3基础入门》课件 第四章 Vue 3组件_第1页
《Vue 3基础入门》课件 第四章 Vue 3组件_第2页
《Vue 3基础入门》课件 第四章 Vue 3组件_第3页
《Vue 3基础入门》课件 第四章 Vue 3组件_第4页
《Vue 3基础入门》课件 第四章 Vue 3组件_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

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

文档简介

Vue3

组件介绍组件是Vue3中最核心的功能之一,可用于前端应用程序的模块化开发,实现系统的可重用性和可扩展性。组件是可复用的实例,在根组件实例中可用的选项也可以在组件中使用。开发人员能使用可复用组件系统构建大型应用程序,几乎所有类型的应用程序界面都可以抽象为一棵组件树。Contents目录快速构建页面组件间数据传递内容分发01020304

其他应用01快速构建页面PART1.1基本使用方法//定义一个名为<button-counter>的新组件Vponent('button-counter',{data:function(){return{count:0}},template:'<buttonv-on:click="count++">Youclickedme{{count}}times.</button>'})1.1基本使用方法组件是可复用的Vue3实例且带有一个名字,在这个例子中是<button-counter>。开发者可以在通过newVue创建的Vue3根实例中,将这个组件作为自定义元素来使用,代码如下:<divid="components-demo">

<button-counter></button-counter></div>组件可以接收与newVue相同的选项,如data、computed、watch、methods以及钩子函数等,但el选项例外。1.2组件复用每当复用一个组件时,都会创建一个独立的组件实例,每个实例都独立维护它的数据。定义<button-counter>组件时,data选项并不是一个对象,而是一个函数,这是因为组件的data选项必须返回一个对象的独立拷贝,以便每个组件实例可以维护自己的一份数据,代码如下:data:function(){return{count:0}}1.3组织结构通常情况下,应用程序会以一棵嵌套的组件树的形式进行组织,如图:需要将组件注册到Vue3实例中才能使用,组件的注册方式分为全局注册和局部注册两种,全局注册组件使用Vue3实例的component()函数,该函数接收两个参数,第一个参数是组件的名称,第二个参数是组件的配置对象或组件的选项。注册的语法形式如下:ponent({string}name,{FunctionIObject}definition(optional))1.3组织结构下面是一个全局注册组件的例子代码:constapp=Vue.createApp({});ponent('ButtonCounter',{data(){return{count:0}},template:'<button@click="count++">Youclickedme{{count}}times.</button>'});app.mount('#app');1.3组织结构1.组件的内容可以通过template选项定义,在使用组件时,组件所在位置会被template选项的内容所替换。组件注册完成后,可以将组件视为自定义元素,在需要的地方按照元素的方式使用,元素的名称就是注册时指定的组件名称。<divid="app"><ButtonCounter></ButtonCounter></div>2.上述代码并不能正常工作,因为HTML并不区分元素和属性的大小写,浏览器会把所有大写字符解释为小写字符,例如:会把<ButtonCounter>解释为<buttoncounter>,这就导致找不到组件而出现错误,解决办法是在HTML模板中采用kebab-case命名引用组件。<divid="app"><button-counter></button-counter></div>1.3组织结构只要组件注册时采用的是PascalCase(首字母大写)命名,就可以采用kebab-case命名来引用。在非HTML模板中可以使用组件的原始名称,即<ButtonCounter>和<button-counter>都是可以的。如果要保持名字的统一性,可以在注册组件时,直接使用kebab-case命名为组件命名,例如:ponent('button-counter',...)1.3组织结构T由于HTML不支持自闭合的自定义元素,在HTML模板中不能将<ButtonCounter>组件当作自闭合元素使用。例如:不能使用<button-counter/>,而应该使用<button-counter></button-counter>。在非HTML模板中不存在这个限制,相反还鼓励将没有内容的组件作为自闭合元素使用,这可以明确表示该组件没有内容,并且省略了结束标记,代码也更加简洁。局部注册是在组件实例的选项对象中使用component选项注册。constMyComponent={data(){return{count:0}},template:'<buttonv-on:click="count++">Youclickedme{{count}}times.</button>'}constapp=Vue.createApp({components:{ButtonCounter:MyComponent}}).mount('#app');对于components选项对象,每个属性的名称就是自定义元素的名称,其属性值就是组件实例。全局注册的组件可以在应用程序的任何组件实例的模板中使用,而局部注册的组件只能在父组件的模板中使用。1.4钩子函数在Vue3中针对钩子函数设计了新的函数,这些函数可以帮助开发者编写更好的代码。Vue3的CompositionAPI提供了一个setup()函数封装了大部分组件代码,并处理了响应式、钩子函数等,可以取代之前的beforeCreate()函数和Create()函数。钩子函数是必须导入到项目中的,这是为了使项目尽可能轻量化。导入方式如下import{onMounted,onUpdated,onUnmounted}from'vue'

1.4钩子函数0102固定栏靠前所谓的固定栏,也就是带有.mui-bar属性的节点,都是基于fixed定位的元素;常见组件包括:顶部导航栏(.mui-bar-nav)、底部工具条(.mui-bar-footer)、底部选项卡(.mui-bar-tab);这些元素使用时需遵循一个规则:放在.mui-content元素之前,即使是底部工具条和底部选项卡,也要放在.mui-content之前,否则固定栏会遮住部分主内容;一切内容都要包裹在mui-content中。除了固定栏之外,其它内容都要包裹在.mui-content中,否则就有可能被固定栏遮罩,原因:固定栏基于Fixed定位,不受流式布局限制,普通内容依然会从top:0的位置开始布局,这样就会被固定栏遮罩,mui为了解决这个问题,定义了如下css代码:.mui-bar-nav~.mui-content{padding-top:44px;}.mui-bar-footer~.mui-content{padding-bottom:44px;}.mui-bar-tab~.mui-content{padding-bottom:50px;}

1.4钩子函数0102旧的钩子函数可以在setup()函数中访问,代码如下:exportdefault{setup(){onBeforeMount(()=>{//...})onMounted(()=>{//...})onBeforeUpdate(()=>{//...})onUpdated(()=>{//...})onBeforeUnmount(()=>{//...})onErrorCaptured(()=>{//...})}}import{onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted,onActivated,onDeactivated,onErrorCaptured}from'vue'02组件间数据传递PART2.1通过props属性传递数据0102使用组件时可以为组件元素设置属性。首先需要在组件内部注册一些自定义属性,称为prop,这些prop是在组件的props选项中定义的,然后就可以将这些prop名称作为元素的属性名来使用,通过属性向组件传递数据。代码如下:Vponent('blog-post',{props:['title'],template:'<h3>{{title}}</h3>'})一个组件默认可以拥有任意数量的prop,任何值都可以传递给任何prop。在上述模板中能够在组件实例中访问title这个值。一个prop被注册之后,就可以像这样把数据作为一个自定义属性传递进来。

2.2通过“总线”传递数据事件总线是Vue3的一个实例,也称作EventBus。定义如下:importVuefrom'vue'exportdefaultnewVue()也可以直接在main.js中直接初始化,代码如下://main.jsVtotype.$EventBus=newVue()。<template><divclass="header"><divclass="header-logo"><imgalt="Vuelogo"src="../../assets/images/common/logo.png"@click="changeCollapse"></div></div></template>发送事件使用的是$emit()函数,该函数包含两个参数:一个是事件名称,一个是参数。以下是一个以ElementUI侧边栏菜单折叠为例的代码:<script>importbusfrom'@/utils/eventBus.js'exportdefault{data(){return{collapse:false}},methods:{changeCollapse(){this.collapse=!this.collapsebus.$emit('collapse',this.collapse)}}}</script>2.2通过“总线”传递数据<template><divclass="sidebar"><el-scrollbarclass="scroll-wrapper"><el-menuclass="sidebar-el-menu":default-active="$route.path":collapse="collapse"unique-openedrouter><subItem:items="items":collapse="collapse"/></el-menu></el-scrollbar><divclass="slideIn"@click="changeCollapse">||</div></div></template>接下来需要在需要响应的组件中接收事件并作出响应,代码如下:<script>importbusfrom"@/utils/eventBus.js"importsubItemfrom"./subitem"exportdefault{props:['items'],data(){return{collapse:false}},created(){bus.$on("collapse",msg=>{this.collapse=msg})},methods:{changeCollapse(){this.collapse=!this.collapsebus.$emit("collapse",this.collapse)}}}</script>2.2通过“总线”传递数据<script>importbusfrom"@/utils/eventBus.js"exportdefault{methods:{handleClick(){bus.$off("collapse",{})//移除单个事件bus.$off()//移除全部事件}}}</script>移除事件可使用$off,单独移除某一个事件的监听需要第一个参数,即事件名称,全部移除则不需要任何参数,代码如下:2.3通过监听事件传递数据前面介绍了父组件可以通过prop向子组件传递数据,反过来,子组件的某些功能需要与父组件进行通信,则可以通过自定义事件实现。子组件使用$emit()函数触发事件,父组件使用v-on指令监听子组件的自定义事件,$emit()函数的语法形式如下:$emit(eventName,[...args])eventName为事件名,args为附加参数,这些参数会传给事件监听器的回调函数。子组件通过第二个参数向父组件传递数据。ponent('child',{data(){return{name:'张三'}},

methods:{handleClick(){//调用实例的$emit()函数触发自定义事件greet,并传递参数

this.$emit('greet',);}},template:'<button@click="handleClick">开始欢迎</button>'})2.3通过监听事件传递数据0102子组件中的按钮接收到click事件后,使用$emit()函数触发一个自定义事件,使用组件时可以使用v-on指令监听greet事件,实现子组件向父组件传递数据,代码如下:<divid="app"><child@greet="sayHello"></child></div>constapp=Vue.createApp({methods:{//自定义事件的附加参数会自动传入函数sayHello(name){alert("Hello,"+name);}}});与组件和prop不同,事件名不会自动转换大小写。调用$emit()函数触发的事件名称需要与用于监听该事件的名称完全匹配。如果在v-on指令中直接使用JavaScript语句,则可以通过$emit()函数访问自定义事件的附加参数,示例代码如下:<button@click="$emit('enlarge-text',0.1)">Enlargetext</button>;03内容分发PART3.1基本使用方法创建组件代码如下:<navigation-linkurl="/profile">YourProfile</navigation-link><navigation-link>模板代码如下:<av-bind:href="url"class="nav-link"><slot></slot></a>当组件渲染时,<slot></slot>将被替换为“YourProfile”,插槽内可以包含任何模板代码或者组件,代码如下:<navigation-linkurl="/profile"><!--添加一个FontAwesome图标--><spanclass="fafa-user"></span>YourProfile</navigation-link><navigation-linkurl="/profile"><!--添加一个图标的组件--><font-awesome-iconname="user"></font-awesome-icon>YourProfile</navigation-link>如果<navigation-link>的模板中没有包含<slot>元素,则该组件起始标签和结束标签之间的内容都会被抛弃。3.2编译作用域在插槽中使用数据的模板代码如下:<navigation-linkurl="/profile">

Loggedinas{{}}</navigation-link>该插槽跟模板的其他地方一样可以访问相同的实例property(也就是相同的“作用域”),而不能访问<navigation-link>的作用域,例如:下方代码中url是访问不到的:<navigation-linkurl="/profile">Clickingherewillsendyouto:{{url}}//这里的'url'会是undefined</navigation-link>3.3后备内容可以给一个插槽设置默认内容,这个内容只会在没有提供内容时被渲染,例如:<button>组件大部分时候渲染文本“Submit”作为默认内容,示例代码如下:<buttontype="submit">

<slot>Submit</slot></button>当在一个父组件中使用<submit-button>并且没有提供任何插槽内容时,将会渲染默认内容“Submit”,如果提供了内容,则会渲染提供的内容,代码如下:<submit-button></submit-button><buttontype="submit">Submit</button><submit-button>Save</submit-button><buttontype="submit">Save</button>3.4具名插槽有时在项目中需要使用多个插槽,<slot>元素有一个特殊的属性name可以用来定义额外的插槽,没有name属性的<slot>元素会有一个隐含的名字“default”。<divclass="container"><header>

<slotname="header"></slot></header><main><slot></slot></main><footer><slotname="footer"></slot></footer></div>3.4具名插槽在向具名插槽提供内容的时候,可以在<template>元素上使用v-slot指令,并以v-slot的参数的形式提供其名称。<base-layout><templatev-slot:header><h1>Heremightbeapagetitle</h1></template><p>Aparagraphforthemaincontent.</p><p>Andanotherone.</p><templatev-slot:footer><p>Here'ssomecontactinfo</p></template></base-layout>

3.4具名插槽<template>元素中的所有内容都将传递到相应的插槽中,任何没有被包裹在带有v-slot的<template>中的内容都将被视为默认插槽的内容。如果希望更明确则可在一个<template>中包括默认插槽的内容,注意v-slot只能添加在<template>上。

<templatev-slot:footer><p>Here'ssomecontactinfo</p></template></base-layout><divclass="container"><header><h1>Heremightbeapagetitle</h1></header><main><p>Aparagraphforthemaincontent.</p><p>Andanotherone.</p></main><footer><p>Here'ssomecontactinfo</p></footer></div><base-layout><templatev-slot:header><h1>Heremightbeapagetitle</h1></template><templatev-slot:default><p>Aparagraphforthemaincontent.</p><p>Andanotherone.</p></template>3.5作用域插槽有时候让插槽内容能够访问子组件中的数据是非常有用的,例如:<current-user>组件想要更改默认内容为user.firstName。

<span><slot>{{user.lastName}}</slot></span><current-user>{{user.firstName}}</current-user>上述代码不能正常工作,因为只有<current-user>组件可以访问到user,而代码中提供的内容是在父级渲染的。为了让user在父级的插槽内容中可用,可以将user作为<slot>元素的一个属性绑定上去。<span><slotv-bind:user="user">{{user.lastName}}</slot></span>绑定在<slot>元素上的属性被称为插槽prop,在父级作用域中可以使用带值的v-slot来定义插槽prop的名字,将包含所有插槽prop的对象命名为slotProps,也可任意命名。

<current-user><templatev-slot:default="slotProps">{{slotProps.user.firstName}}</template></current-user>

3.6动态插槽名动态指令参数也可以用在v-slot上,来定义动态的插槽名,代码如下:<base-layout><templatev-slot:[dynamicSlotName]>...

温馨提示

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

评论

0/150

提交评论