微信小程序封装了一些基础的组件,使用起来很方便,但定制化程度不高,日常开发中难免有一些功能想要做成组件,在其他地方复用。在网上找了好久,有很多小程序模块化框架,比如labrador,wx-component,但是都不敢用。一方面这些框架都比较年轻,不敢轻易用到项目中;另一方面改了微信原先的page,app构造函数,不确定因素太多,指不定哪天出什么乱子。
今天看到一哥们写的小程序自定义公众组件,感觉简单靠谱。
其核心思想:
1、组件页面template,依赖组件的页面<import>
2、@import组件样式
3、组件逻辑:
在组件构造函数中获取到当前页面对象:
let pages = getCurrentPages()let curPage = pages[pages.length - 1]
然后分别将组件的事件,方法复制到curPage中:
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 = curPageObject.assign(curPage, _comEvent, _comMethod)curPage.setData(_comData)curPage.loginPanel = thisreturn 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中引入组件样式
@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(); //使用组件方法}
})
最终结果: