小程序组件化

微信小程序封装了一些基础的组件,使用起来很方便,但定制化程度不高,平常开发中不免有一些功能想要作成组件,在其余地方复用。在网上找了很久,有不少小程序模块化框架,好比labradorwx-component,可是都不敢用。一方面这些框架都比较年轻,不敢轻易用到项目中;另外一方面改了微信原先的page,app构造函数,不肯定因素太多,指不定哪天出什么乱子。
今天看到一哥们写的小程序自定义公众组件,感受简单靠谱。git


其核心思想:

一、组件页面template,依赖组件的页面<import>
二、@import组件样式
三、组件逻辑:
在组件构造函数中获取到当前页面对象:github

let pages = getCurrentPages()
    let curPage = pages[pages.length - 1]

而后分别将组件的事件,方法复制到curPage中:json

Object.assign(curPage,_comData,_comMethod)

设置组件数据:小程序

curPage.setData({_comData})

登录组件为例:微信小程序

项目结构

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

login.wxml

<template name="login"> 
    <view class="__lgpanel_mask" wx:if="{{!isHide}}">
        <view class="__lgpanel">
            <view class="__lgpanel_title">登陆</view>
            <view class="__lgpanel_username">
                <text>用户名:</text>
                <input type="number" value="{{phone}}" />
            </view>
            <view class="__lgpanel_pwd">
                <text>密码:</text>
                <input type="number" value="{{password}}"/>
            </view>
            <view class="__lgpanel_login">
                <button size="mini" type="primary" bindtap="__lgpanel_ok">肯定</button>
                <button size="mini" type="warn" bindtap="__lgpanel_cancel">取消</button>
            </view>
        </view>
    </view>
 </template>

login.wxss

/* login.wxss */
.__lgpanel_mask{
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(0, 0, 0, 0.3);
    display: flex;
    flex-direction: column;
    justify-content: center;
    z-index: 10;
}

.show{
    display: block;
}

.hide{
    display: none;
}

.__lgpanel{
    font-family: "微软雅黑", 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
    width: 80vw;
    margin: 0 auto;
    background: white;
    border: 2rpx solid #e3e3e3;
    border-radius: 8rpx;
    padding: 20rpx;
}

.__lgpanel_title{
    display: block;
    text-align: center;
    margin: 10rpx;
    padding-bottom: 10rpx;
    border-bottom: 2rpx solid #ff9900;
}

.__lgpanel_username,.__lgpanel_pwd{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    margin: 40rpx 10rpx;
}

.__lgpanel_username text,.__lgpanel_pwd text{
    flex-shrink: 0;
    width: 30%;
}

.__lgpanel_login{
    display: flex;
    justify-content: space-around;
}

login.js

// 组件数据
let _comData = {
    '__lgpanel__.phone':182*****535,
    '__lgpanel__.password':123456,
    '__lgpanel__.isHide':true
}
//组件事件
let _comEvent = {
    __lgpanel_ok:function(){
        console.log('OK')
        this.__lgpanel_hide()
    },
    __lgpanel_cancel:function(){
        console.log('Cancel')
        this.__lgpanel_hide()
    }
}
//方法
let _comMethod = {
    __lgpanel_show:function(){
        this.setData({'__lgpanel__.isHide':false})
    },
    __lgpanel_hide:function(){
        this.setData({'__lgpanel__.isHide':true})
    }
}
//组件类
function LoginPanel(){
    let pages = getCurrentPages()
    let curPage = pages[pages.length - 1]
    //组件中调用页面
    this._page = curPage
    Object.assign(curPage, _comEvent, _comMethod)
    curPage.setData(_comData)

    curPage.loginPanel = this
    return this
}

export { LoginPanel }

在index页面中使用login组件

1.index.wxml中引入login组件模板微信

<import src="../../components/login/login.wxml"/>
<view class="container">
  <template is="login" data="{{...__lgpanel__}}"></template>
  <button type="default" plain bindtap="login">登陆</button>
</view>

2.index.wxss中引入组件样式app

@import '../../components/login/login.wxss';

3.index.js中注册组件框架

import { LoginPanel } from '../../components/login/login'
Page({
    data: {
    },
    onLoad: function () {
        new LoginPanel()  //注册组件
    },
    login: function () {
        this.__lgpanel_show();    //使用组件方法
    }
})

最终结果:
图片描述xss