小程序的组件和api
组件
1 2 3
| https: 一个小程序页面可以分解成多个部分组成,组件就是小程序页面的基本组成单元。为了让开发者可以快速进行开发,小程序的宿主环境提供了一系列基础组件。 组件是在WXML模板文件声明中使用的,WXML的语法和HTML语法相似,小程序使用标签名来引用一个组件,通常包含开始标签和结束标签,该标签的属性用来描述该组件。
|
组件共有属性
1 2 3 4 5 6 7
| 属性名 类型 描述 其他说明 id String 组件的唯一标示 保持整个页面唯一 class String 组件的样式类 在对应的WXSS中定义的样式类 style String 组件的内联样式 可以通过数据绑定进行动态设置的内联样式 hidden Boolean 组件是否显示 所有组件默认显示 data-* Any 自定义属性 组件上触发的事件时,会发送给事件处理函数 bind / catch EventHandler 事件 详情见3.5节
|
自定义组件
新建文件夹(所有组件component)
里面,新建组件文件夹(swiper)
里面,新建组件文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| swiper.wxml <view class="inner"> {{innerText}} </view> swiper.wxss .inner { color: red; } swiper.json { "component": true } swiper.js Component({ properties: { innerText: { type: String, value: 'default value', } }, data: { someData: {} }, methods: { customMethod: function(){} } })
|
组件的引用
seiper 任意组件名字
page1.json(需要引用组建的页面)
1 2 3 4 5 6 7 8 9 10
| { "usingComponents": { "seiper": "../component/swiper/swiper" } } page1.wxml(需要引用组建的页面) <view> <seiper inner-text="Some text"></seiper> </view>
|
swiper组件 案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| swiper.wxml <!--pages/component/swiper/swiper.wxml--> <view class="page-body"> <view class="page-section page-section-spacing swiper"> <swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" circular="{{circular}}" vertical="{{vertical}}" interval="{{interval}}" duration="{{duration}}" previous-margin="{{previousMargin}}px" next-margin="{{nextMargin}}px"> <block wx:for="{{background}}" wx:key="*this"> <swiper-item> <view> <image src="/pages/img/1-s-benner.png"></image> </view> </swiper-item> </block> </swiper> </view> </view>
swiper.js const app = getApp()
Page({ data: { motto: 'Hello World', userInfo: {}, hasUserInfo: false, canIUse: wx.canIUse('button.open-type.getUserInfo'), background: ['demo-text-1', 'demo-text-2', 'demo-text-3'], indicatorDots: true, vertical: false, autoplay: true, circular: true, interval: 3000, duration: 500, previousMargin: 0, nextMargin: 0 }, })
swiper.json { "component": true, "usingComponents": {} } swiper.wxss
page { background-color: #F8F8F8; height: 100%; font-size: 32rpx; line-height: 1.6; } .page-body{ background-color: pink; } .page-section{ width: 100%; } .page-section_center{ display: flex; flex-direction: column; align-items: center; } .page-section:last-child{ margin-bottom: 0; } .page-section-gap{ box-sizing: border-box; padding: 0 30rpx; } .page-section-spacing{ box-sizing: border-box; } .page-section-title{ font-size: 28rpx; color: #999999; margin-bottom: 10rpx; padding-left: 30rpx; padding-right: 30rpx; } .page-section-gap .page-section-title{ padding-left: 0; padding-right: 0; } button{ margin-bottom: 30rpx; } button:last-child{ margin-bottom: 0; } .page-section-title{ padding: 0; } swiper{ height: 370rpx; } swiper-item{ display: block; height: 100%; width: 100%; } swiper-item >view{ width: 100%; height: 100%; } swiper-item >view image{ width: 100%; height: 100%; } .page-section-title{ margin-top: 60rpx; position: relative; } .info{ position: absolute; right: 0; color: #353535; font-size: 30rpx; } .page-foot{ margin-top: 50rpx; }
|
三级联动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| https://developers.weixin.qq.com/miniprogram/dev/component/picker.html wxml <picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}"> <view class="picker"> {{region[0]}}{{region[1]}}{{region[2]}} {{region[1]}} </view> </picker> js data: { region: ['广东省', '广州市', '海珠区'], customItem: '全部' }, bindRegionChange: function (e) { console.log('picker发送选择改变,携带值为', e.detail.value) this.setData({ region: e.detail.value }) },
就可以了 mode可以选择不同类型 multiSelector time date region(地区选择器)
|
组件传值
组件传值(父传子)
页面A
1 2 3 4 5 6 7 8 9 10 11 12
| wxml <titleimg paramAtoB="/pages/img/1-s-xinpintuijian.png"></titleimg> paramAtoB 任意参数名 json { "usingComponents": { "swiper": "/pages/component/swiper/swiper", "navbox": "/pages/component/navbox/navbox", "titleimg": "/pages/component/titleimg/titleimg" } }
|
组件页面B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| wxml <view class="titleimg"> <image mode='widthFix' src="{{paramAtoB}}"></image> </view> 直接使用 js Component({ behaviors: [], properties: { paramAtoB: String }, data: {
},
attached: function () { }, moved: function () { }, detached: function () { }, methods: {
}
|
组件传值(子传父)
子组件内部准备参数
html
1 2 3 4 5 6 7 8 9
| <view class="navbox"> <view class="navbox_ul" > <view bindtap="tap_fn" data-id="A"> <image src="/pages/img/1-s-NEW.png"></image> <text>新品推荐</text> </view> </view> </view>
|
js
1 2 3 4 5 6 7 8 9
| tap_fn:function(e){ console.log(1111111111, e.currentTarget.dataset.id) var scrollTopId = e.currentTarget.dataset.id; this.triggerEvent('myevent', scrollTopId)
},
|
父组件接收参数
navbox 是我的父组件名
myevent 我的事件名
scrollTopId 我随意起的函数名称
html
1 2
| <navbox bind:myevent="scrollTopId"> </navbox>
|
js
e里面有我的参数
1 2 3
| scrollTopId:function(e){ console.log(e); },
|
API
小程序提供的API按照功能主要分为几大类
网络、媒体、文件、数据缓存、位置、设备、界面、界面节点信息还有一些特殊的开放接口
为了让开发者可以很方便的调起微信提供的能力,例如获取用户信息、微信支付等等,小程序提供了很多 API 给开发者去使用。
要获取用户的地理位置时,只需要:
1 2 3 4 5 6 7
| wx.getLocation({ type: 'wgs84', success: (res) => { var latitude = res.latitude var longitude = res.longitude } })
|
调用微信扫一扫能力,只需要:
1 2 3 4 5
| wx.scanCode({ success: (res) => { console.log(res) } })
|
更多api功能参考官方文档
https://developers.weixin.qq.com/miniprogram/dev/api/
API一般调用的约定:
1 2 3 4 5
| wx.on* 开头的 API 是监听某个事件发生的API接口,接受一个 Callback 函数作为参数。当该事件触发时,会调用 Callback 函数。 如未特殊约定,多数 API 接口为异步接口 ,都接受一个Object作为参数。 API的Object参数一般由success、fail、complete三个回调来接收接口调用结果,示例代码如代码清单3-17所示,详细说明如表3-9所示。 wx.get* 开头的API是获取宿主环境数据的接口。 wx.set* 开头的API是写入数据到宿主环境的接口。
|
wx.request
通过wx.request发起网络请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| wx.request({ url: 'test.php', data: {}, header: { 'content-type': 'application/json' }, success: function(res) { // 收到https服务成功后返回 console.log(res.data) }, fail: function() { // 发生网络错误等情况触发 }, complete: function() { // 成功或者失败后触发 } })
代表3-9 API接口回调说明
参数名字 类型 必填 描述 success Function 否 接口调用成功的回调函数 fail Function 否 接口调用失败的回调函数 complete Function 否 接口调用结束的回调函数(调用成功、失败都会执行)
|
事件
常见的事件类型
1 2 3 4 5 6 7 8 9 10 11
| touchstart 手指触摸动作开始 touchmove 手指触摸后移动 touchcancel 手指触摸动作被打断,如来电提醒,弹窗 touchend 手指触摸动作结束 tap 手指触摸后马上离开 longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 longtap 手指触摸后,超过350ms再离开(推荐使用longpress事件代替) transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 animationstart 会在一个 WXSS animation 动画开始时触发 animationiteration 会在一个 WXSS animation 一次迭代结束时触发 animationend 会在一个 WXSS animation 动画完成时触发
|
简单事件代码演示
1 2 3 4 5 6 7 8 9
| <view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
// page.js Page({ tapName: function(event) { console.log(event) } })
|
事件对象属性
1 2 3 4 5 6 7
| type String 事件类型 timeStamp Integer 页面打开到触发事件所经过的毫秒数 target Object 触发事件的组件的一些属性值集合 currentTarget Object 当前组件的一些属性值集合 detail Object 额外的信息 touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组 changedTouches Array 触摸事件,当前变化的触摸点信息的数组
|
事件对象实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <view id="outer" catchtap="handleTap"> <view id="inner">点击我</view> </view> // page.js Page({ handleTap: function(evt) { // 当点击inner节点时 // evt.target 是inner view组件 // evt.currentTarget 是绑定了handleTap的outer view组件 // evt.type == “tap” // evt.timeStamp == 1542 // evt.detail == {x: 270, y: 63} // evt.touches == [{identifier: 0, pageX: 270, pageY: 63, clientX: 270, clientY: 63}] // evt.changedTouches == [{identifier: 0, pageX: 270, pageY: 63, clientX: 270, clientY: 63}] } })
|
target和currentTarget事件对象属性
属性 类型 说明
id String 当前组件的id
tagName String 当前组件的类型
dataset Object 当前组件上由data-开头的自定义属性组成的集合
属性 类型 说明
identifier Number 触摸点的标识符
pageX, pageY Number 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
clientX, clientY Number 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
事件绑定与冒泡捕获
事件绑定的写法和组件属性一致,以key=”value”的形式,其中:
key以bind或者catch开头,然后跟上事件的类型,如bindtap、catchtouchstart。自基础库版本1.5.0起,bind和catch后可以紧跟一个冒号,其含义不变,如bind:tap、catch:touchstart。同时bind和catch前还可以加上capture-来表示捕获阶段。
value是一个字符串,需要在对应的页面Page构造器中定义同名的函数,否则触发事件时在控制台会有报错信息。
bind和capture-bind的含义分别代表事件的冒泡阶段和捕获阶段
capture-bind 事件捕获
bind 事件冒泡
capture-catch 将中断捕获阶段和取消冒泡阶段
点击 inner view 会先后调用handleTap2、handleTap4、handleTap3、handleTap1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2" > outer view <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4" > inner view </view> </view>
|
bind和catch
bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2(capture-catch将中断捕获阶段和取消冒泡阶段)
滑动事件
用的就是
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| bindtouchstart="scrollTouchstart" bindtouchmove="scrollTouchmove" bindtouchend="scrollTouchend"
js
Page({ data: { scrollindex: 0, totalnum: 5, starty: 0, endy: 0, critical: 100, margintop: 0, }, onLoad: function () { }, scrollTouchstart: function (e) { console.log('滚动到顶部'); console.log(e.touches[0].pageY); let py = e.touches[0].pageY; this.setData({ starty: py }) }, scrollTouchmove: function (e) { console.log('滚动中'); let py = e.touches[0].pageY; let d = this.data; this.setData({ endy: py, }) if (py - d.starty < 100 && py - d.starty > -100) { this.setData({ margintop: py - d.starty }) } }, scrollTouchend: function (e) { console.log('滚动到底部'); let d = this.data; if (d.endy - d.starty > 100 && d.scrollindex > 0) { this.setData({ scrollindex: d.scrollindex - 1 }) } else if (d.endy - d.starty < -100 && d.scrollindex < this.data.totalnum - 1) { this.setData({ scrollindex: d.scrollindex + 1 }) } this.setData({ starty: 0, endy: 0, margintop: 0 }) }, })
|
自定义属性,事件中获取
设置自定义属性
取值自定义属性
1 2 3 4 5 6 7
| <view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view> Page({ bindViewTap:function(event){ event.currentTarget.dataset.alphaBeta === 1 event.currentTarget.dataset.alphabeta === 2 } })
|
获取取路由参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| A页面:WXML <button bindtap="GoHome" open-type="launchApp" data-index="123">进入餐厅</button>
A页面:js page内即可
GoHome: function (e) { wx.navigateTo({ url: "../HomePage/HomePage?UName=" + e.target.dataset.index, }) }
B页面:js data内先声明一个参数,用以接收值
data: { UName:'' },
onload内写,自动获取
onLoad: function (options) { this.setData({ UName: options.UName }) console.log(this.data.UName) },
|