微信小程序> 小程序自定义组件一-小程序自定义组件意义-微信小程序组件开发

小程序自定义组件一-小程序自定义组件意义-微信小程序组件开发

浏览量:1934 时间: 来源:寒生1988
自定义组件从小程序基础库版本1.6.3开始,小程序支持简洁的组件化编程。所有自定义组件相关特性都需要基础库版本1.6.3或更高。

开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。

创建自定义组件类似于页面,一个自定义组件由jsonwxmlwxssjs4个文件组成。要编写一个自定义组件,首先需要在json文件中进行自定义组件声明(将component字段设为true可这一组文件设为自定义组件):

{"component":true}同时,还要在wxml文件中编写组件模版,在wxss文件中加入组件样式,它们的写法与页面的写法类似。具体细节和注意事项参见组件模版和样式。

代码示例:

!--这是自定义组件的内部WXML结构--viewclass"inner"{{innerText}}/viewslot/slot/*这里的样式只应用于这个自定义组件*/.inner{color:red;}注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

在自定义组件的js文件中,需要使用Component()来注册组件,并提供组件的属性定义、内部数据和自定义方法。

组件的属性值和内部数据将被用于组件wxml的渲染,其中,属性值是可由组件外部传入的。更多细节参见Component构造器。

代码示例:

Component({properties:{//这里定义了innerText属性,属性值可以在组件使用时指定innerText:{type:String,value:'defaultvalue',}},data:{//这里是一些组件内部数据someData:{}},methods:{//这里是一个自定义方法customMethod:function(){}}})使用自定义组件使用已注册的自定义组件前,首先要在页面的json文件中进行引用声明。此时需要提供每个自定义组件的标签名和对应的自定义组件文件路径:

{"usingComponents":{"component-tag-name":"path/to/the/custom/component"}}这样,在页面的wxml中就可以像使用基础组件一样使用自定义组件。节点名即自定义组件的标签名,节点属性即传递给组件的属性值。

代码示例:

view!--以下是对一个自定义组件的引用--component-tag-nameinner-text"Sometext"/component-tag-name/view自定义组件的wxml节点结构在与数据结合之后,将被插入到引用位置内。

Tips:

对于基础库的1.5.x版本,1.5.7也有部分自定义组件支持。因为WXML节点标签名只能是小写字母、中划线和下划线的组合,所以自定义组件的标签名也只能包含这些字符。自定义组件也是可以引用自定义组件的,引用方法类似于页面引用自定义组件的方式(使用usingComponents字段)。自定义组件和使用自定义组件的页面所在项目根目录名不能以“wx-”为前缀,否则会报错。旧版本的基础库不支持自定义组件,此时,引用自定义组件的节点会变为默认的空节点。组件模版和样式类似于页面,自定义组件拥有自己的wxml模版和wxss样式。

组件模版组件模版的写法与页面模板相同。组件模版与组件数据结合后生成的节点树,将被插入到组件的引用位置上。

在组件模板中可以提供一个slot节点,用于承载组件引用时提供的子节点。

代码示例:

!--组件模板--viewclass"wrapper"view这里是组件的内部节点/viewslot/slot/view!--引用组件的页面模版--viewcomponent-tag-name!--这部分内容将被放置在组件slot的位置上--view这里是插入到组件slot中的内容/view/component-tag-name/view注意,在模版中引用到的自定义组件及其对应的节点名需要在json文件中显式定义,否则会被当作一个无意义的节点。除此以外,节点名也可以被声明为抽象节点。

组件wxml的slot在组件的wxml中可以包含slot节点,用于承载组件使用者提供的wxml结构。

默认情况下,一个组件的wxml中只能有一个slot。需要使用多slot时,可以在组件js中声明启用。

Component({options:{multipleSlots:true//在组件定义时的选项中启用多slot支持},properties:{/*...*/},methods:{/*...*/}})此时,可以在这个组件的wxml中使用多个slot,以不同的name来区分。

!--组件模板--viewclass"wrapper"slotname"before"/slotview这里是组件的内部细节/viewslotname"after"/slot/view使用时,用slot属性来将节点插入到不同的slot上。

!--引用组件的页面模版--viewcomponent-tag-name!--这部分内容将被放置在组件slotname"before"的位置上--viewslot"before"这里是插入到组件slotname"before"中的内容/view!--这部分内容将被放置在组件slotname"after"的位置上--viewslot"after"这里是插入到组件slotname"after"中的内容/view/component-tag-name/view组件样式组件对应wxss文件的样式,只对组件wxml内的节点生效。编写组件样式时,需要注意以下几点:

组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用class选择器。组件和引用组件的页面中使用后代选择器(.a.b)在一些极端情况下会有非预期的表现,如遇,请避免使用。子元素选择器(.a.b)只能用于view组件与其子节点之间,用于其他组件可能导致非预期的情况。继承样式,如font、color,会从组件外继承到组件内。除继承样式外,app.wxss中的样式、组件所在页面的的样式对自定义组件无效。#a{}/*在组件中不能使用*/[a]{}/*在组件中不能使用*/button{}/*在组件中不能使用*/.a.b{}/*除非.a是view组件节点,否则不一定会生效*/除此以外,组件可以指定它所在节点的默认样式,使用:host选择器(需要包含基础库1.7.2或更高版本的开发者工具支持)。

代码示例:

/*组件custom-component.wxss*/:host{color:yellow;}!--页面的WXML--custom-component这段文本是黄色的/custom-component外部样式类有时,组件希望接受外部传入的样式类(类似于view组件的hover-class属性)。此时可以在Component中用externalClasses定义段定义若干个外部样式类。这个特性从小程序基础库版本1.9.90开始支持。

代码示例:

/*组件custom-component.js*/Component({externalClasses:['my-class']})!--组件custom-component.wxml--custom-componentclass"my-class"这段文本的颜色由组件外的class决定/custom-component这样,组件的使用者可以指定这个样式类对应的class,就像使用普通属性一样。

代码示例:

!--页面的WXML--custom-componentmy-class"red-text"/.red-text{color:red;}Component构造器Component构造器可用于定义组件,调用Component构造器时可以指定组件的属性、数据、方法等。

定义段类型是否必填描述propertiesObjectMap否组件的对外属性,是属性名到属性设置的映射表,属性设置中可包含三个字段,type表示属性类型、value表示属性初始值、observer表示属性值被更改时的响应函数dataObject否组件的内部数据,和properties一同用于组件的模版渲染methodsObject否组件的方法,包括事件响应函数和任意的自定义方法,关于事件响应函数的使用,参见组件事件behaviorsStringArray否类似于mixins和traits的组件间代码复用机制,参见behaviorscreatedFunction否组件生命周期函数,在组件实例进入页面节点树时执行,注意此时不能调用setDataattachedFunction否组件生命周期函数,在组件实例进入页面节点树时执行readyFunction否组件生命周期函数,在组件布局完成后执行,此时可以获取节点信息(使用SelectorQuery)movedFunction否组件生命周期函数,在组件实例被移动到节点树另一个位置时执行detachedFunction否组件生命周期函数,在组件实例被从页面节点树移除时执行relationsObject否组件间关系定义,参见组件间关系externalClassesStringArray否组件接受的外部样式类,参见外部样式类optionsObjectMap否一些组件选项,请参见文档其他部分的说明生成的组件实例可以在组件的方法、生命周期函数和属性observer中通过this访问。组件包含一些通用属性和方法。

属性名类型描述isString组件的文件路径idString节点iddatasetString节点datasetdataObject组件数据,包括内部数据和属性值方法名参数描述setDataObjectnewData设置data并执行视图层渲染hasBehaviorObjectbehavior检查组件是否具有behavior(检查时会递归检查被直接或间接引入的所有behavior)triggerEventStringname,Objectdetail,Objectoptions触发事件,参见组件事件createSelectorQuery创建一个SelectorQuery对象,选择器选取范围为这个组件实例内selectComponentStringselector使用选择器选择组件实例节点,返回匹配到的第一个组件实例对象selectAllComponentsStringselector使用选择器选择组件实例节点,返回匹配到的全部组件实例对象组成的数组getRelationNodesStringrelationKey获取所有这个关系对应的所有关联节点,参见组件间关系代码示例:

Component({behaviors:[],properties:{myProperty:{//属性名type:String,//类型(必填),目前接受的类型包括:String,Number,Boolean,Object,Array,null(表示任意类型)value:'',//属性初始值(可选),如果未指定则会根据类型选择一个observer:function(newVal,oldVal){}//属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串,如:'_propertyChange'},myProperty2:String//简化的定义方式},data:{},//私有数据,可用于模版渲染//生命周期函数,可以为函数,或一个在methods段中定义的方法名attached:function(){},moved:function(){},detached:function(){},methods:{onMyButtonTap:function(){this.setData({//更新属性和数据的方法与更新页面数据的方法类似})},_myPrivateMethod:function(){//内部方法建议以下划线开头this.replaceDataOnPath(['A',0,'B'],'myPrivateData')//这里将data.A[0].B设为'myPrivateData'this.applyDataUpdates()},_propertyChange:function(newVal,oldVal){}}})注意:在properties定义段中,属性名采用驼峰写法(propertyName);在wxml中,指定属性值时则对应使用连字符写法(component-tag-nameproperty-name"attrvalue"),应用于数据绑定时采用驼峰写法(attr"{{propertyName}}")。

Tips:

Component构造器构造的组件也可以作为页面使用。使用this.data可以获取内部数据和属性值,但不要直接修改它们,应使用setData修改。生命周期函数无法在组件方法中通过this访问到。属性名应避免以data开头,即不要命名成dataXyz这样的形式,因为在WXML中,data-xyz""会被作为节点dataset来处理,而不是组件属性。在一个组件的定义和使用时,组件的属性名和data字段相互间都不能冲突(尽管它们位于不同的定义段中)。组件事件事件系统是组件间交互的主要形式。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。关于事件的基本概念和用法,参见事件。

监听自定义组件事件的方法与监听基础组件事件的方法完全一致:

代码示例:

!--当自定义组件触发“myevent”事件时,调用“onMyEvent”方法--component-tag-namebindmyevent"onMyEvent"/!--或者可以写成--component-tag-namebind:myevent"onMyEvent"/Page({onMyEvent:function(e){e.detail//自定义组件触发事件时提供的detail对象}})自定义组件触发事件时,需要使用triggerEvent方法,指定事件名、detail对象和事件选项:

代码示例:

!--在自定义组件中--buttonbindtap"onTap"点击这个按钮将触发“myevent”事件/buttonComponent({properties:{}methods:{onTap:function(){varmyEventDetail{}//detail对象,提供给事件监听函数varmyEventOption{}//触发事件的选项this.triggerEvent('myevent',myEventDetail,myEventOption)}}})触发事件的选项包括:

选项名类型是否必填默认值描述bubblesBoolean否false事件是否冒泡composedBoolean否false事件是否可以穿越组件边界,为false时,事件将只能在引用组件的节点树上触发,不进入其他任何组件内部capturePhaseBoolean否false事件是否拥有捕获阶段关于冒泡和捕获阶段的概念,请阅读事件章节中的相关说明。

代码示例:

//页面page.wxmlanother-componentbindcustomevent"pageEventListener1"my-componentbindcustomevent"pageEventListener2"/my-component/another-component//组件another-component.wxmlviewbindcustomevent"anotherEventListener"slot//view//组件my-component.wxmlviewbindcustomevent"myEventListener"slot//view//组件my-component.jsComponent({methods:{onTap:function(){this.triggerEvent('customevent',{})//只会触发pageEventListener2this.triggerEvent('customevent',{},{bubbles:true})//会依次触发pageEventListener2、pageEventListener1this.triggerEvent('customevent',{},{bubbles:true,composed:true})//会依次触发pageEventListener2、anotherEventListener、pageEventListener1}}})

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎