小程序自定义组件

发布一下 0 0

小程序中的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)            }        }    }})

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/82756.html