小程序中的js对象实例,按作用域大小划分,大致可以归为三类:App, Page, Component。
Component 也即本文要重点要讲的自定义组件,或称模板。
一、App
App() 必须在 app.js 中调用且只能调用一次,用于注册成为一个小程序应用。
1、app.js
App({ // 小程序初始化完成时触发,全局只触发一次。 onLaunch (options) { // 通过options.scene获取场景值可以得到小程序进入的渠道来源 // 参数也可以使用 wx.getLaunchOptionsSync 获取。 }, // 小程序启动,或从后台进入前台显示时触发。 onShow (options) { // 小程序启动,或从后台进入前台显示时触发。 }, // 小程序从前台进入后台时触发。 onHide () { // 也可以使用 wx.onAppHide 绑定监听。 }, onError (msg) { console.log(msg) }, // 小程序要打开的页面不存在时触发。也可以使用 wx.onPageNotFound 绑定监听。 onPageNotFound(res) { // 如果是 tabbar 页面,需使用 wx.switchTab // 若需保留历史页面路径,需用wx.navigateTo,而非wx.redirectTo (会销毁当前页面) // 若存在循环操作,则需要计算页面层级(wx.navigateTo最多跳转10层页面,超过会报页面栈溢出) let pageNum = getCurrentPages().length if(pages >= 10){ // 超过页面路由层深,返回重载应用首页 wx.reLaunch({ url: '/pages/index/index' }) }else{ wx.navigateTo({ url: '/pages/...' }) } // 控制后退页面数 wx.navigateBack(); wx.navigateBack({delta: n}); // 后退n页 wx.navigateBack({ // 回退所有循环操作页面,只保留前3页 delta: pageNum - 3, // iOS会先重定向后回退页面,需要控制先回退完成后再重定向到指定页面 complete: function(){ wx.redirectTo({ url: '/pages/...' }) } }) }, // 全局数据,可以保存用户登录信息等 globalData: { }})
2、app.json
app.json 全局配置(所有页面需要在此文件中注册配置pages。该文件不能写注释。)
{ "pages": [ "pages/index/index" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "我的小程序", "navigationBarTextStyle": "black" }, "permission": { "scope.userLocation": { "desc": "你的位置信息将用于定位效果展示" } }, "style": "v2", "sitemapLocation": "sitemap.json", "tabBar": { "color": "#333333", "selectedColor": "#333333", "selectedFontweight": "600", "backgroundColor": "#fff", "list": [ { "pagePath": "pages/index/index", "iconPath": "/img/icon_index0.png", "selectedIconPath": "/img/icon_index1.png", "text": "首页" }, { "pagePath": "pages/mine/mine", "iconPath": "/img/icon_mine0.png", "selectedIconPath": "/img/icon_mine1.png", "text": "我的" } ] }}
二、Page
1、/pages/chat-list/chat-list.js
import Api from '../../api.js';Page({ /** * 页面的初始数据 */ data: { userId: 0, pageNum: 1, chats: [], noMoreChatData: false, noMoreUserData: false }, // 扫码 scanCode(){ // 这一步重命名赋值变量,是为了在回调函数内部能够获取当前页面对象 let that = this wx.scanCode({ onlyFromCamera: true, success (res) { // {"charSet":"utf-8","result":"32","codeVersion":1,"errMsg":"scanCode:ok","rawData":"MzI=","scanType":"QR_CODE"} if(res.result == that.data.userId){ wx.showToast({ title: '扫码成功' }) }else{ wx.showToast({ title: '二维码无效', icon: 'none' }) } }, fail (res) { wx.showToast({ title: res, icon: 'none' }) } }) }, // 弹框下拉选菜单 chooseMenu() { let that = this wx.showActionSheet({ itemList: ['离职-随时到岗', '在职-月内到岗', '在职-考虑机会', '在职-暂不考虑'], // 不能超过6个 success (res) { // todo something } }) }, // 订阅服务消息通知(后台服务器按模板ID推送通知,小程序订阅接收) subscribeNotice(){ wx.requestSubscribeMessage({ tmplIds: ['o-ztPlfmck2B6yWFey_pLloT3CxUqLrbXnX-FvfiWlo'], success: (res) => {} }) }, // 页面锚点 pageScrollTo(){ wx.pageScrollTo({ selector:'#footer', // 滚动至指定节点元素id duration: 0 // 滚动过渡时间 }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // 可以通过options获取上级页面路由路径传参 let userId = options.userId this.setData({ userId: userId }) }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { // 一般会在页面显示时,请求服务加载数据,动态渲染页面展示 this.getChatsByPage() // 禁止页面分享菜单(shareAppMessage分享给朋友;shareTimeline分享到朋友圈) wx.hideShareMenu({ menus: ['shareAppMessage', 'shareTimeline'] }) }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { // wx.redirectTo 会触发当前页面销毁 // 一般也会在页面销毁时(包括onHide时),关闭当前页面的定时器 }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { // 该事件默认关闭,需要在页面对应的json配置文件中开启 "enablePullDownRefresh": true // 比如聊天页面,后台服务按时间倒序返回聊天记录,前端第一页拉取最新的聊天记录,下拉刷新拉取历史聊天记录 // 下拉刷新,获取下一页历史聊天数据列表 this.getChatsByPage() }, // 获取聊天数据列表 getChatsByPage(){ if(!this.data.noMoreChatData){ this.setData({ pageNum: this.data.pageNum + 1 }) // 前端拉取的每一页记录,逆序处理后,追加到当前数据列表的头部 let chats = Api.getChatsByPage() // 分页查询,从后台服务器拉取聊天记录数据 if(chats != null && chats.length > 0){ chats.sort(function(a, b){return a['id'] - b['id']}) // 逆序处理:数组属性获取方法,重写排序规则要return that.setData({ chats: chats.concat(that.data.chats) // 头部插入数组 }) }else{ that.setData({ noMoreChatData: true }) } } }, // 分页查询数据列表(触底onReachBottom后若有更多数据再请求) noMoreUserData(e) { // 参数值由子组件user-list触发trigger传递过来 this.setData({ noMoreUserData: e.detail }) }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { // 分页查询处理 if (!this.data.noMoreUserData) { // 获取子组件 user-list this.userList = this.selectComponent("#userList") // 调用子组件的方法 this.userList.getDataList() } }, /** * 用户点击右上角分享(移除该函数,则整个页面禁止分享) */ onShareAppMessage: function () { }})
2、/pages/chat-list/chat-list.json
页面对应的json配置文件:引用组件;开启下拉刷新监听;设置标题栏
{ "usingComponents": { "user-list": "/components/user-list/user-list" }, "enablePullDownRefresh": true, "navigationBarTitleText": "聊天列表"}
3、/pages/chat-list/chat-list.wxml
<view class="chat-list"> <!-- 引用子组件模板,user-list标签需与chat-list.json中引入并设定的组件名保持一致; 设定的id,用于chat-list.js中获取子组件对象:this.userList = this.selectComponent("#userList") userId 为父传子交互属性, 对应子组件user-list.js的properties中定义的属性userId bind:noMoreUserData 用于子组件user-list.js中trigger触发父组件方法noMoreUserData --> <user-list id="userList" userId="{{userId}}" bind:noMoreUserData="noMoreUserData" /></view>
三、Component
如果诸多Page间存在一些反复重复部分,可以选择新建Component,抽取出公共部分作为模板引用,也即自定义组件,从而达到复用的目的。
组件json配置,声明为组件(当然,组件内部还可以再嵌套引用其他组件):
1、/components/user-list/user-list.json
{ "component": true, "usingComponents": { "no-more": "/components/no-more/no-more" }}
2、/components/user-list/user-list.js
import Api from '../../api.js'// 子组件 user-listComponent({ /** * 组件的属性列表 (父传子交互属性) */ properties: { userId: Number }, /** * 组件的初始数据 (子组件私有数据,data中可以获取到properties中的传参值) */ data: { userId: 0, dataList: [], pageNum: 1, noMoreData: false }, /** * 组件的方法列表 */ methods: { // 子组件中定义的方法,父组件中获取到子组件对象后,可以调用子组件方法 getDataList() { // 获取数据列表 let dataList = Api.getDataList() if(dataList.length > 0){ this.setData({ dataList: this.data.dataList.concat(dataList), pageNum: pageNum + 1 }) }else{ this.setData({ noMoreData: true }) // 子组件user-list, 触发父组件对象绑定的监听方法 this.triggerEvent('noMoreUserData', true) } } }})
版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除