微信小程序> 写一个微信小程序自定义公共组件

写一个微信小程序自定义公共组件

浏览量:1904 时间: 来源:u前端人

微信小程序已经推出一段时间了,官方也提供很多组件,但是有些业务场景,官方组件难免有些捉襟见肘,这时候,就需要自己开发一个自定义组件了。但是微信小程序其实是做了很多限制的,本文记录了开发(踩坑)一个公共登录弹出框组件的过程,仅供参考。

1. 一个组件的组成部分

一个微信小程序有四中格式的文件*.wxml*.wxss*.js*.json*.json其实是小程序和页面的配置文件,开发组件的时候,就不需要这个了。我这里开发一个登陆弹出框组件,我把组件放在component文件夹下:

123456789101112131415
Wechat-APP/├─app.js├─app.json├─app.wxss├─component/│ └─login-pannel/│   ├─login-pannel.js│   ├─login-pannel.wxml│   └─login-pannel.wxss├─image/├─pages/│ ├─index/│ ├─merchant-detail/│ └─merchant-list/└─utils/

可见,组件也是由三个部分组成。

1.1. wxml

首先新建组件的模版,/component/login-pannel/login-pannel.wxml,同时,给定义的模版一个唯一标识template name="loginPannel"/template,代码如下:

123456789101112131415
template name="loginPannel"  view class="login-pannel" hidden="{{ isHide }}"     view catchtap="__lgpanel_close" class="close-btn"/view    view class="form-area"      view class="login-inline phone {{ phoneClass }}"        input placeholder="请填写手机号码" maxlength="11" type="number" bindinput="__lgpanel_phoneInput" bindfocus="__lgpanel_phoneFocus" bindblur="__lgpanel_phoneBlur" /        text catchtap="__lgpanel_sendCode" class="verify-btn"{{ verifyText }}/text      /view      view class="login-inline vcode {{ vcodeClass }}"        input placeholder="请填写验证码" maxlength="4" type="number" bindinput="__lgpanel_vcodeInput" bindfocus="__lgpanel_vcodeFocus" bindblur="__lgpanel_vcodeBlur" /      /view    /view    text catchtap="__lgpanel_login" class="login-btn"注册/登录/text  /view/template

官方提供了模版的概念,同时又给出了两种引用方式:import 和 include。include 方式是将你的模版原封不动的“粘贴”到引用的地方,而我们这里开发的是一个交互组件,势必会碰到数据绑定和事件绑定,所以我们最终引用的时候,使用 import 的形式来使用组件。

1.2. wxss

定义组件的样式,/component/login-pannel/login-pannel.wxss。样式没什么好说的,这里略过。

1.3. js

首先定义组件的构造函数,构造函数主要做两件事:

  • 把组件的数据“注入”到页面的data对象中;
  • 把组件的事件“合并”到页面对象上。

小程序文档中,关于数据和事件,是这么描述的:

  • 如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
  • WXML 中的动态数据均来自对应 Page 的 data。
  • 模板拥有自己的作用域,只能使用 data 传入的数据。

这样,想实现模版的数据绑定,只能想办法把组件上的数据“追加”到页面的 data 对象上去;同理,想实现组件的事件绑定,则需要把组件的事件也“传给”页面函数Page。同时,为了防止影响到其它组件,还要给数据和事件都限定了“命名空间”:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
let _compData = {  '__lgpanel__.isHide': true,  '__lgpanel__.phoneNum': '',  '__lgpanel__.verifyCode': '',  '__lgpanel__.verifyText': '获取验证码',  '__lgpanel__.phoneClass': '',  '__lgpanel__.vcodeClass': ''}let _compEvent = {  __lgpanel_timer: null,  __lgpanel_countDown: 60,  __lgpanel_close: function () {    clearInterval(this.__lgpanel_timer)    this.__lgpanel_countDown = 60    this.setData(_compData)  },  __lgpanel_sendCode: function () {    if (this.__lgpanel_countDown  60) {      return    }    this.setData({      '__lgpanel__.verifyText': this.__lgpanel_countDown + 's'    })        this.__lgpanel_timer = setInterval(() = {      this.__lgpanel_countDown--      if (this.__lgpanel_countDown = 0) {        clearInterval(this.__lgpanel_timer)        this.__lgpanel_countDown = 60        this.setData({          '__lgpanel__.verifyText': '重新获取'        })        return      }      this.setData({        '__lgpanel__.verifyText': this.__lgpanel_countDown + 's'      })    }, 1000)    typeof this.loginPannel._configs.sendCode == "function" &&      this.loginPannel._configs.sendCode()  }}// 小程序最新版把原型链干掉了。。。换种写法let loginPannel = {  show: function(data) {    this.__page.setData({'__lgpanel__.isHide': false})    if (data) {      Object.assign(this._configs, data)    }  }}function LoginPannel () {  // 定义组件的一些回调  this._configs = {    sendCode: null,    closeCode: null,    login: null  }  // 拿到当前页面对象  let pages = getCurrentPages()  let curPage = pages[pages.length - 1]  // 把组件的事件“合并到”页面对象上
            
            

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

最新资讯

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎