自定义组件:
创建组件:
按照以下步骤即可,

4,在wxml 文件中国做好节点布局 ,在wxss 中做好样式,
使用组件:

这种方式有点类似于 模板,但是它比模板更加强大,(模板只是 将代码拷贝过来,而自定义组件除了样式,也可以做一些逻辑处理 )。
给自定义组件添加属性:



在外部使用的时候,可以使用默认值,也可以给其赋值,


在组件中添加节点:
在使用小程序内置的组件的时候,比如view,我们还可以在view中添加其他的组件。这个功能可以通过slot节点来实现。


以后有 需要的话,可以直接在 slot位置插入我们想要的组件,
添加多个slot :

例子:



使用的时候:

效果如下:

组件样式:
组件对应 wxss 文件的样式,只对组件wxml内的节点生效。编写组件样式时,需要注意以下几点:
- 组件和引用组件的页面不能使用id选择器(
#a)、属性选择器([a])和标签名选择器,请改用class选择器。 - 组件和引用组件的页面中使用后代选择器(
.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。 - 子元素选择器(
.a>.b)只能用于view组件与其子节点之间,用于其他组件可能导致非预期的情况。 - 继承样式,如
font、color,会从组件外继承到组件内。 - 除继承样式外,
app.wxss中的样式、组件所在页面的的样式对自定义组件无效(除非更改组件样式隔离选项)。

除此以外,组件可以指定它所在节点的默认样式,使用 :host 选择器(需要包含基础库 1.7.2 或更高版本的开发者工具支持)。
自定义组件 的事件 (使用this.triggerEvent() 来自定义 事件!!) :
这里我们主要看的是如何给组件自定义事件,(内置的事件直接使用即可),
自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项:
自定义组件事件。直接在组件内绑定事件。并且如果我们想在组件内捕获到事件后,要通知到父组件,那么可以通过triggerEvent方法来触发自定义的事件。

触发事件的选项包括:
| 选项名 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
| bubbles | Boolean | 否 | false | 事件是否冒泡 |
| composed | Boolean | 否 | false | 事件是否可以穿越组件边界,为false时,事件将只能在引用组件的节点树上触发,不进入其他任何组件内部 |
| capturePhase | Boolean | 否 | false | 事件是否拥有捕获阶段 |
代码:
自定义组件代码:
1 <view> 2 <view>这是固定的内容</view> 3 <view class="box"> 4 <view class="left" bindtap="onClickEvt" data-idx="0"> 5 左 6 <slot name="lf"></slot> 7 </view> 8 <view class="right" bindtap="onClickEvt" data-idx="1"> 9 右 10 <slot name="rt"></slot> 11 </view> 12 </view> 13 14 </view>
1 // components/mybox/mybox.js 2 Component({ 3 options:{ 4 multipleSlots:true 5 }, 6 /** 7 * 组件的属性列表 8 */ 9 properties: { 10 }, 11 12 /** 13 * 组件的初始数据 14 */ 15 data: { 16 17 }, 18 19 /** 20 * 组件的方法列表 21 */ 22 methods: { 23 onClickEvt:function(evt){ 24 // 根据 idx 来判断是左面点击 还是右面点击 25 //然后将 idx 的值 通知到外部 !! 26 var idx = evt.currentTarget.dataset.idx; 27 28 var detail = {idx:idx}; 29 var option = {} 30 this.triggerEvent("myClickEvt",detail,option); 31 32 } 33 } 34 })
1 .box{ 2 height: 500rpx; 3 background-color: cyan; 4 display: flex; 5 } 6 .left,.right{ 7 width: 50%; 8 height: 100%; 9 border: 1px solid #ff0; 10 box-sizing: border-box; 11 }
{
"component": true,
"usingComponents": {}
}
使用自定义组件的代码:
1 <mybox bindmyClickEvt="clickEvt"> 2 <view slot="lf">我是左面的内容</view> 3 <view slot="lf">我也是左面的内容</view> 4 5 <view slot="rt">我是右面</view> 6 <view slot="rt">我是右面</view> 7 </mybox>
1 Page({ 2 3 /** 4 * 页面的初始数据 5 */ 6 data: { 7 8 }, 9 10 /** 11 * 生命周期函数--监听页面加载 12 */ 13 onLoad: function (options) { 14 15 }, 16 clickEvt:function(evt){ 17 console.log(evt); 18 var idx = evt.detail.idx; 19 if(idx == '0'){ 20 console.log("左面被点击了"); 21 } 22 if( idx == '1'){ 23 console.log("右面被点击了"); 24 } 25 26 } 27 })
1 { 2 "usingComponents":{ 3 "mybox":"/components/mybox/mybox" 4 } 5 }

组件本身的生命周期:
组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。
其中,最重要的生命周期是created/attached/detached,包含一个组件实例生命流程的最主要时间点。(注意:在2.2.3基础库之前,生命周期函数写在Component中就可以,在2.2.3后应该写在lifetimes中。)
- 组件实例刚刚被创建好时,
created生命周期被触发。此时,组件数据this.data就是在Component构造器中定义的数据data。此时还不能调用setData。通常情况下,这个生命周期只应该用于给组件this添加一些自定义属性字段。 - 在组件完全初始化完毕、进入页面节点树后,
attached生命周期被触发。此时,this.data已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。 - 在组件离开页面节点树后,
detached生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则detached会被触发。
我们这里微信版本 使用的是 2.10.1

监听组件所在页面的生命周期 事件 :
还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理。这样的生命周期称为“组件所在页面的生命周期”,
在 pageLifetimes 定义段中定义。其中可用的生命周期包括:
只能监听组件所在页面的 以下三个事件:(onLoad 是不能被执行的,)
| 生命周期 | 参数 | 描述 | 最低版本 |
|---|---|---|---|
| show | 无 | 组件所在的页面被展示时执行 | 2.2.3 |
| hide | 无 | 组件所在的页面被隐藏时执行 | 2.2.3 |
| resize | Object Size | 组件所在的页面尺寸变化时执行 | 2.4.0 |

自定义组件 案例 -- segement 实现:
什么是segement :

就是类似于上图的这种,
自定义组件segement 代码:
1 <!--components/segement/segement.wxml--> 2 3 <view class="box"> 4 <view class="top" bindtap="onClickEvt"> 5 <block wx:for="{{arr}}" wx:key="*this"> 6 <view wx:if="{{index == selectedIdx }}" data-id="{{index}}" class="active">{{item}}</view> 7 <view wx:else data-id="{{index}}" >{{item}}</view> 8 </block> 9 </view> 10 </view>
1 /* components/segement/segement.wxss */ 2 .box{ 3 width: 100%; 4 height: 100rpx; 5 /* background-color: gray; */ 6 } 7 .top{ 8 width: 100%; 9 height: 100%; 10 /* background-color: cyan; */ 11 display: flex; 12 justify-content: space-evenly; 13 align-items: center; 14 15 } 16 .top view{ 17 width: 33.333%; 18 height: 50%; 19 border: 1px solid #ccc; 20 border-right: none; 21 text-align: center; 22 background-color: #fff; 23 24 border-radius: 4px; 25 } 26 .top view:last-of-type{ 27 border-right: 1px solid #ccc; 28 } 29 .top .active{ 30 background-color: #1AAD16; 31 color: #fff; 32 }
1 // components/segement/segement.js 2 Component({ 3 /** 4 * 组件的属性列表 5 */ 6 properties: { 7 arr:{ 8 type:Array, 9 value:[] 10 }, 11 selectedIdx:{ 12 type:Number, 13 value:0 14 } 15 16 }, 17 18 /** 19 * 组件的初始数据 20 */ 21 data: { 22 23 }, 24 25 /** 26 * 组件的方法列表 27 */ 28 methods: { 29 onClickEvt:function(evt){ 30 var idx = evt.target.dataset.id; 31 var detail = {idx:idx}; 32 var option = {}; 33 this.triggerEvent("myEvt",detail,option); 34 35 } 36 37 } 38 })
1 { 2 "component": true, 3 "usingComponents": {} 4 }
使用segement 的代码:
1 <segement arr="{{myarr}}" 2 selectedIdx="{{idx}}" 3 bindmyEvt="clickTabEvt" 4 ></segement> 5 <view class = "bottom" 6 style="background-color:{{color[idx]}};"> 7 {{myarr[idx]}}的内容 8 </view>
1 .bottom{ 2 width: 100%; 3 height: 800rpx; 4 }
1 Page({ 2 3 /** 4 * 页面的初始数据 5 */ 6 data: { 7 myarr:['最新','关注','同城'], 8 idx:0, 9 color:["yellow","red","green"] 10 }, 11 12 /** 13 * 生命周期函数--监听页面加载 14 */ 15 onLoad: function (options) { 16 17 }, 18 clickTabEvt:function(evt){ 19 var idx = evt.detail.idx; 20 this.setData({idx:idx}); 21 // console.log("idx 为: "+idx); 22 } 23 })
1 { 2 "usingComponents":{ 3 "segement":"/components/segement/segement" 4 } 5 }
效果如下:

自定义组件补充 observers :

网络请求api :
小程序中的数据,并不是写死的。而是从服务器动态加载的。
这时候就需要借助网络请求的api来实现。api全称application programming interface,是小程序提供给开发者的接口。
api的调用都是在js文件中完成的。
网络请求的api相关的介绍请参考:https://developers.weixin.qq.com/miniprogram/dev/api/wx.request.html。
wx.request() :
RequestTask wx.request(Object object)
发起 HTTPS 网络请求。使用前请注意阅读相关说明。
参数 Object object
| 属性 | 类型 | 默认值 | 必填 | 说明 | 最低版本 |
|---|---|---|---|---|---|
| url | string | 是 | 开发者服务器接口地址 | ||
| data | string/object/ArrayBuffer | 否 | 请求的参数 | ||
| header | Object | 否 | 设置请求的 header,header 中不能设置 Referer。content-type 默认为 application/json |
||
| timeout | number | 否 | 超时时间,单位为毫秒 | 2.10.0 | |
| method | string | GET | 否 | HTTP 请求方法 | |
| dataType | string | json | 否 | 返回的数据格式 | |
| responseType | string | text | 否 | 响应的数据类型 | 1.7.0 |
| success | function | 否 | 接口调用成功的时候进行 回调的 函数 | ||
| fail | function | 否 | 接口调用失败的时候进行 回调的 函数 | ||
| complete | function | 否 | 接口调用结束的回调函数(成功、失败都会执行) |
object.method 的合法值
| 值 | 说明 | 最低版本 |
|---|---|---|
| OPTIONS | HTTP 请求 OPTIONS | |
| GET | HTTP 请求 GET | |
| HEAD | HTTP 请求 HEAD | |
| POST | HTTP 请求 POST | |
| PUT | HTTP 请求 PUT | |
| DELETE | HTTP 请求 DELETE | |
| TRACE | HTTP 请求 TRACE | |
| CONNECT | HTTP 请求 CONNECT |
object.dataType 的合法值
| 值 | 说明 | 最低版本 |
|---|---|---|
| json | 返回的数据为 JSON,返回后会对返回的数据进行一次 JSON.parse | |
| 其他 | 不对返回的内容进行 JSON.parse |
object.responseType 的合法值
| 值 | 说明 | 最低版本 |
|---|---|---|
| text | 响应的数据为文本 | |
| arraybuffer | 响应的数据为 ArrayBuffer |
object.success 回调函数
参数 Object res
| 属性 | 类型 | 说明 | 最低版本 |
|---|---|---|---|
| data | string/Object/Arraybuffer | 开发者服务器返回的数据 | |
| statusCode | number | 开发者服务器返回的 HTTP 状态码 | |
| header | Object | 开发者服务器返回的 HTTP Response Header | 1.2.0 |
| cookies | Array.<string> | 开发者服务器返回的 cookies,格式为字符串数组 | 2.10.0 |
返回值
RequestTask
基础库 1.4.0 开始支持,低版本需做兼容处理。
请求任务对象
data 参数说明
最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String 。转换规则如下:
- 对于
GET方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...) - 对于
POST方法且header['content-type']为application/json的数据,会对数据进行 JSON 序列化 - 对于
POST方法且header['content-type']为application/x-www-form-urlencoded的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...)

什么时候应该进行网络请求:
当页面加载完毕之后,就应该网络请求,然后把数据 setData() 到我们的data中,
聚合网站(juhe.cn) 笑话大全案例:
暂缺