模板html
<!-- 组件模板 -->
<view class="wrapper">
<slot name="before"></slot>
<view>这里是组件的内部节点</view>
<slot name="after"></slot>
</view>
模板json
{
"component": true,
"usingComponents": {}
}
模板css
/* components/
组件对应 wxss 文件的样式,只对组件wxml内的节点生效。编写组件样式时,需要注意以下几点:
组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用class选择器。
组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
继承样式,如 font 、 color ,会从组件外继承到组件内。
除继承样式外, 中的样式、组件所在页面的的样式对自定义组件无效。
组件可以指定它所在节点的默认样式,使用 :host 选择器
*/
#a { } /* 在组件中不能使用 */
[a] { } /* 在组件中不能使用 */
button { } /* 在组件中不能使用 */
.a > .b { } /* 除非 .a 是 view 组件节点,否则不一定会生效 */
:host{
color:blueviolet;
}
模板js
// components/
Component({
// externalClasses: ['my-class'], ///组件希望接受外部传入的样式类
options: {
multipleSlots: true // 在组件定义时的选项中启用多slot支持(一般只支持一个)多个slot,以不同的 name 来区分。
},
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
sayHello(e){
(e,'hello')
}
}
})
引入页json文件
{
"usingComponents": {
"my-component": "/components/component-tag-name"
}
}
引入页html
<!-- 引用组件的页面模版 -->
<view>
<my-component>
<!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
<view slot="before">这里是插入到组件slot中的内容</view>
<view slot="after">这里是after插入到组件slot中的内容</view>
</my-component>
</view>
Component构造器/miniprogram/dev/framework/custom-component/
数据传入components
组件html
注意:在 properties 定义段中,属性名采用驼峰写法(propertyName);在 wxml 中,指定属性值时则对应使用连字符写法(component-tag-name property-name=”attr value”),应用于数据绑定时采用驼峰写法(attr=”{{propertyName}}”)。
Component({
behaviors: [],
properties: {
myProperty: { // 属性名
type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: '', // 属性初始值(可选),如果未指定则会根据类型选择一个
observer: function (newVal, oldVal) {
// (oldVal)
// (newVal)
} // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange'
},
myProperty2: String // 简化的定义方式
},
data: {
A: [{
B: 'init [0].B'
}]
}, // 私有数据,可用于模版渲染
// 生命周期函数,可以为函数,或一个在methods段中定义的方法名
attached: function () { },
moved: function () { },
detached: function () { },
methods: {
onMyButtonTap: function () {
this.setData({
// 更新属性和数据的方法与更新页面数据的方法类似
myProperty: 'Test'
})
},
_myPrivateMethod: function () {
// 内部方法建议以下划线开头
this.replaceDataOnPath(['A', 0, 'B'], 'myPrivateData') // 这里将 [0].B 设为 'myPrivateData'
this.applyDataUpdates()
},
_propertyChange: function (newVal, oldVal) {
}
}
})
引入页html
<my-component my-property="{{msg}}" />
triggerEvent 使用
组件js
// components/
Component({
properties: {},
methods: {
onTap: function () {
var myEventDetail = {a:111} // detail对象,提供给事件监听函数
var myEventOption = {} // 触发事件的选项
this.triggerEvent('myevent', myEventDetail, myEventOption)
}
}
})
引用页js
const app = getApp()
Page({
data: {
},
myEventListener: function(e) {
()
}
})
触发事件的选项包括:
选项名 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
bubbles | Boolean | 否 | false | 事件是否冒泡 |
composed | Boolean | 否 | false | 事件是否可以穿越组件边界,为false时,事件将只能在引用组件的节点树上触发,不进入其他任何组件内部 |
capturePhase | Boolean | 否 | false | 事件是否拥有捕获阶段 |
事件案例/miniprogram/dev/framework/custom-component/
behaviors行为/miniprogram/dev/framework/custom-component/
字段的覆盖和组合规则
组件和它引用的 behavior 中可以包含同名的字段,对这些字段的处理方法如下:
如果有同名的属性或方法,组件本身的属性或方法会覆盖 behavior 中的属性或方法,如果引用了多个 behavior ,在定义段中靠后 behavior 中的属性或方法会覆盖靠前的属性或方法;
如果有同名的数据字段,如果数据是对象类型,会进行对象合并,如果是非对象类型则会进行相互覆盖;
生命周期函数不会相互覆盖,而是在对应触发时机被逐个调用。如果同一个 behavior 被一个组件多次引用,它定义的生命周期函数只会被执行一次。