小程序技能进阶回忆录 - 在缺少组件化的日子里
战争,信念,意志和情感,这些散发着光芒和硝烟的词汇,象一枚枚炮弹轰入我们现在的生活。历史的记忆不会被抹灭。 当我们在各自项目里幸福的拷贝着官方代码 demo,在? 当时,主要有两种解决方法,一种是 WePY 拷贝法,另一种则是 template 法。 WePY 拷贝法比如有个最简单的按钮组件: <!-- components/button.wpy -->
<template>
<view class="button">
<button @tap="onTap">点这里</button>
</view>
</template>
<!-- pages/index.wpy -->
<"container">
<wpy-button /> // button 组件1
<wpy-button2 /> // button 组件2
</template>
复制代码
经过编译后结果如下: <"container">
<button bindtap="$wpyButton$onTap">点这里</view>
<"$wpyButton2$onTap">点这里</view>
复制代码
为了方便变量隔离,所以引入到页面中的组件得单独命名: import wepy from 'wepy'
import Button from '@/components/button'
export default class Index extends wepy.page {
components = {
'wpy-button': Button,'wpy-button2': Button
}
...
}
复制代码
如果多个页面引入同一组件会拷贝多份,有一些不便的地方,但也很好的解决了当时组件化缺失的问题。 template 法有心的同学可能记得当初我们发了这篇文章:?微信小程序组件化解决方案wx-component?,当时主要讲了如何使用,这次讲讲技术的细节。 主要利用小程序当时提供的? <!-- pages/login/index.wxml -->
<import src='../../components/login/index.wxml'/>
<"login-box">
<template is="login" data="{{...}}"></template>
</view>
复制代码
由于知道这只是临时的解决方法,最终还会迁移到微信官方组件化方案。了解到微信团队正在开发,就死皮赖脸找了微信研发同学要下技术方案,以便后期迁移成本做到最低。最后微信同学不耐烦的扔给我们如下代码,并特别嘱咐?不要泄露出去?-_-: Component({
// 组件名
name: '',// 为其他组件指定别名
using: {},136);">// 类似mixins,组件间代码复用
behaviors: [],136);">// 组件私有数据
data: {
},136);">// 外部传入的组件属性
propties: {
},136);">// 当组件被加载
attached () {
},136);">// 当组件被卸载
detached () {
},136);">// 组件私有方法
methods: {
}
})
复制代码
一目了然,依照此文档实现一个简单的组件化方案也有了思路。 如何引入组件由于没有办法在小程序全局注入? // components/login/index.wxml
<form bindsubmit="onLoginSubmit">
...
<button type="primary" formType="submit">{{btnText}}</form>
</template>
复制代码
// components/login/index.js
module.exports = {
name: 'login',data: {
btnText: ''
}
....
}
复制代码
,onLoginCallback() { ... } } } }) 复制代码 在?
有个细节,为了让大家容易理解,分享到外部用? 自定的 Page 怎么写整理了大致的核心代码如下: ,'onUnload'
]
MyPage {
constructor (origin) {
this.origin = origin
this.config = {}
this.children = {}
this.childrenEvents = {}
// 是否需要`components`
let components = this.components = origin.components
if (components) {
this.config.data = {}
for (let item in components) {
let props = components[item] || {}
let component = new Component(require(`../components/${item}/index`))
this.children[name] = component
// 合并组件的 data
extend(component.data,component.props)
// ...
// 合并组件的 method
let fnName in component.methods) {
this.config[fnName] = component.methods[fnName].bind(component)
}
// ...
let childrenEvents = this.childrenEvents[item] = {}
LIFETIME_EVENT.forEach((prop) => {
childrenEvents[item][prop] = component.config[prop]
})
}
// 合并所有依赖组件的生命周期函数
LIFETIME_EVENT.forEach((prop) => {
this.config[prop] = () => {
this.components) {
this.childrenEvents[item][prop].apply(this.component,arguments)
}
this.origin[prop] && this.origin[prop].apply(this,0);">arguments)
}
})
// 把新生成的 config 传给原始的微信的 Page 方法
originalPage(this.config)
} else {
// 没有依赖组件,直接透传给微信的 Page 方法
originalPage(origin)
}
}
}
复制代码
可能有点乱,其实就是不断 merge? 最后,导出自定义的? app.js?中覆盖掉原有的?
广告时间美团单车事业部(摩拜单车)诚招前端 / 小程序研发工程师,有兴趣可以发简历到 zhangshibing@mobike.com ) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |