微信小程序组件化开发代码实现:
仅从组件功能的角度来看,wepy已满足小程序的大多数组件开发需求,这是完美的。
但是,如果您权衡整个项目:
您需要在开发之前检查开发文档,并以与小程序完全不同的方式编写小程序。对于那些不熟悉MVVM开发的人来说,有一定的学习成本,不利于开发人员熟悉小程序(就像直接使用React.js进行开发的前端开发初学者一样,很难像原生JS操作DOM的“相对低级”知识这样的东西。
在开发过程中,还需要在预览和调试之前进行实时编译,这会花费一定的时间。
编译后的代码无法正常运行。是写作问题,编译问题还是框架问题?调试起来很复杂。
因此,wepy更适合大型小程序(当您有足够的理由使用它时),如Vuex官方文档中所述:如果您的应用程序足够简单,则最好不要使用Vuex。一个简单的全局事件总线就足够了。
对于中小型小程序,如何更好地实现组件化?
wxss使用@import引号而没有异议。
对于模板,由于我们使用include方法来引用,因此只能通过像wepy这样的命名来隔离作用域。最简单的方法是将组件名称添加为前缀。例如:
1.// src/components/tab.wxml 2.> 3. bindtap="tabChange(0)"> 4. src="../images/message{{tabActive == 0 ? '_active' : ''}}.png">image> 5.>微信text> 6.view> 7.... 8.view>
对于js,您可以简单地将其封装到一个对象中,然后将其直接与页面对象合并:
1.// src/components/tab.js 2.export default class { 3.data: { 4.tabActive: { 5.twoWay: true 6.} 7.}, 8.change (idx, evt) { 9.this.active = +idx; 10.} 11.}
许多人会想到这样打电话:
1.// src/pages/index.wxml 2."../components/tab.wxml"/> 3.... 4.// src/pages/index.js 5.import tab from '../components/tab.js' 6.let page = { 7.... 8.} 9.Object.assign(page, tab) 10.Page(page)
直接使用Object.assign的最大缺点是父页面无法侦听组件事件。例如,在示例中单击选项卡选项卡时,选项卡组件需要更改样式,并且父页面也需要侦听此事件以显示相应的内容。
在另一种情况下,例如,当组件初始化还需要使用父页面的data属性时,则父页面需要在初始化完成后调用组件本身的初始化函数。
在onLoad中顺序调用?这样,需要对每个组件进行判断和调用。过多的垃圾代码也容易出错。显然,该代码不够简短且健壮。
凭借MVVM框架的开发经验,我们可以使用Vue.js中的mixin思想解决此问题。
混合组件和页面对象。对于组件中的data属性,我们仍然使用Object.assign方法进行复制,因为我们只需要区分组件对象中的数据类型和事件函数,即可删除数据层。对于事件,我们需要同时触发组件事件和页面事件,因此我们需要编写一段代码来实现它。最终组件的定义和调用可以进行如下修改:
1.// src/components/tab.js 2.export default class { 3.tabActive: { 4.twoWay: true 5.}, 6.change (idx, evt) { 7.this.active = +idx; 8.} 9.} 10.// src/pages/index.js 11.import tab from '../components/tab.js' 12.import {combine} from '../util.js' 13.let page = { 14.tabClick(event) { 15.... 16.} 17.... 18.} 19.combine(page, tab) 20.Page(page)
对于Combine函数,您只需确定数据类型,然后执行相应的操作即可。
1.// util.js 2./** 3.* 组件对象与页面对象融合 4.* @param {Object} target 页面对象 5.* @param {Object} source 组件对象,支持不定参数 6.* return {Object} 返回一个融合后的页面对象 7.*/ 8.let combine = (target, ...source) => { 9.source.forEach(function(arg) { 10.if('object' === typeof arg) { 11.for(let p in arg) { 12.if('object' === typeof arg[p]) { 13.// 对于对象,直接采用 Object.assign 14.target[p = target[p || {} 15.Object.assign(target[p], arg[p]) 16.} else if('function' === typeof arg[p]) { 17.// 函数进行融合,先调用组件事件,然后调用父页面事件 18.let fun = target[p ? target[p : function(){} 19.delete target[p 20.target[p = function() { 21.arg[p].apply(this, arguments) 22.fun.apply(this, arguments) 23.} 24.} else { 25.// 基础数据类型,直接覆盖 26.target[p = target[p || arg[p 27.} 28.} 29.} 30.}) 31.} 32.export default { 33.combine 34.}
此解决方案似乎很简单,可以实现组件化,但是存在一个问题,即组件重用。
如果在同一页面中同时使用多个选项卡组件,则会出现麻烦,因为相同的组件没有通过命名隔离,因此会产生影响。
只能通过修改组件本身或以其他方式来支持该解决方案,但是幸运的是,这种需求不会出现在大多数页面上。
摘要
对于大型项目,有学习能力的开发人员可以使用wepy(一种出色的小程序框架(构建工具和代码))。
对于中小型项目和初学者,混合方法可以满足组件开发的需求。