主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情! |
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作 |
微信小程序中如何自定义组件?下面这篇文章给大家介绍一下微信小程序中自定义组件的方法,希望对你有所帮助!
在微信小程序的开发过程中,可以将一些可能在多个页面中使用的页面模块封装成一个组件,提高开发效率。虽然我们可以介绍整个组件库,比如weui,vant等。,有时考虑到微信小程序的包容量限制,通常将其打包成自定义组件更可控。
对于一些业务模块,我们可以将其封装为组件重用。本文主要谈以下两个方面:
组件的声明和使用组件的通信组件的声明以及使用微信小程序的组件系统底层是通过Exparser组件框架实现的,该框架内置在小程序的基础库中。applets中的所有组件,包括内置组件和定制组件,都由Exparser组织和管理。
像编写页面一样,自定义组件包含以下文件:
index . json index . wxmlindex . wxsindex . jsindex . wxs以编写tab组件为例:编写自定义组件时,需要在JSON文件中说component字段设置为true:
{ 组件 :true}在js文件中,基本库提供了两个构造器,Page和Component。页面对应的页面是页面根组件,组件对应:
component({ options:{//component configuration addGlobalClass:true,//将所有以_开头的数据字段指定为纯数据字段。//纯数据字段是一些不用于界面渲染的数据字段。PureDataPattern:/_/,multiple slot:true//可以用来提高页面更新的性能。定义组件时在选项中启用多个插槽},属性:{v tabs: {type: array,value:
在电商/物流等微信小程序中,会有这样的用户故事,有一个“订单页面A”和一个“商品信息页面B”
当您需要下钻至“详细信息页面B”以填写“订单页面A”中的基本信息时。例如,如果您要发送一个快递订单页面,您需要钻取到商品信息页面以填写更详细的信息,然后返回到上一个页面。当你从“订单页A”下钻到“商品页B”时,你需要回显“商品页B”的数据。微信小程序由一个app()实例和多个页面()组成。applet框架维护堆栈中的页面(最多10个页面),并提供以下用于页面跳转的API。页面路由如下
Wx.navigateTo(只能跳转位于堆栈中的页面)
Wx.redirectTo(可以跳转到堆栈外的新页面,替换当前页面)
Wx.navigateBack(返回上一页,无参数)
Wx.switchTab(切换选项卡页面,不支持url参数)
Wx.reLaunch(小程序重启)
您可以简单地封装jumpTo跳转函数并传递参数:
导出函数jumpTo(url,options){ const base URL = URL . split( # 39;马鞭 # 39;)[0];//如果url有参数,需要在options If(URL . index of( # 39;马鞭 # 39;) != = -1){ const { queries } = resolve URL(URL);Object.assign(选项、查询、选项);//选项优先级最高} cosnt查询string = objectentries (options)。过滤器(item = >;item[1]| | item[0]= = 0)//除了数字0,所有非值都被过滤。map (([key,value])= >;{ if(type of value = = = # 39;对象 # 39;){//object to string value = JSON . string ify(value);} if(type of value = = = # 39;字符串 # 39;){//string encode value = encodeuricomponent(value);} return ` $ { key } = $ { value }} ).加入( # 39; ');If (queryString) {//需要组装参数url = `${baseUrl}?$ { query string } `;} const page count = wx . getcurrentpages()。长度;if(jump type = = = # 39;导航到 # 39; pageCount lt5) { wx.navigateTo({ url,fail:()= gt;{ wx . switch({ URL:base URL });} });} else { wx.navigateTo({ url,fail:)= gt;{ wx . switch({ URL:base URL });} });} }跳转到辅助功能:
export const resolve search = search = gt;{常量查询= { };cosnt param list = search . split( # 39; ');param list . foreach(param = gt;{ const [key,value = # 39']= param . split( # 39;=');查询[键] =值;});返回查询;};export const resolveUrl =(URL)= gt;{ if(URL . index of( # 39;马鞭 # 39;)=== -1) {// URL return {queries: {},page: URL}} const [page,search]= URL . split( # 39;马鞭 # 39;);const queries = resolveSearch(搜索);返回{ page,queries };};在“订单页面a”上传输数据:
jump to({ URL: # 39;页数/寄售/索引 # 39;,{发件人:{姓名: # 39;naluduo233 # 39} }});获取“商品信息页面B”中的URL参数:
const sender = JSON . parse(getParam( # 39;发件人 # 39;) || '{}');参数采集辅助功能
//返回当前页面导出函数get current page(){ const page stack = wx . getcurrentpages();const last index = page stack . length -1;const current page = page stack[last index];返回当前页面;}//获取页面url参数export function getparams(){ constcurrentpage = getcurrentpage()| | { };const all params = { };const { route,options } =当前页面;if(options){ const entries = object entries(options);entries.forEach( ([key,value])= gt;{ all params[key]= decodeURIComponent(value);} );}返回allParams}//返回值导出函数get param(name){ const params = get params()| | { } by字段;return params[name];}参数太长怎么办?路由api不支持携带参数?
虽然微信小程序的官方文档没有规定参数可以在页面上携带多长时间,但仍然可能存在参数过长被截断的风险。
我们可以使用全局数据记录参数值,解决url参数过长和路由api不支持携带参数的问题。
// global-data.js//由于switchTab不支持携带参数,所以需要考虑使用全局数据存储。//不管是不是switchTab,先把数据挂载在const query map = { page: # 39;',查询:{ } };更新跳转功能
导出函数jumpTo(url,选项){ //...Object.assign(queryMap,{ page: baseUrl,queries:options });// ...if(jump type = = = # 39;switchTab # 39){ wx . switch tab({ URL:base URL });} else if(jump type = = = # 39;导航到 # 39; pageCount lt5) { wx.navigateTo({ url,fail:()= gt;{ wx . switch({ URL:base URL });} });} else { wx.navigateTo({ url,fail:)= gt;{ wx . switch({ URL:base URL });} });} }获取辅助函数的url参数
//获取页面url参数export function getparams(){ constcurrentpage = getcurrentpage()| | { };const all params = { };const { route,options } =当前页面;if(options){ const entries = object entries(options);entries.forEach( ([key,value])= gt;{ all params[key]= decodeURIComponent(value);} );+if (isTabBar(route)) {+ //是tab-bar页面,使用全局挂载的参数+const {page,queries } = queryMap+if(page = = = ` $ { route } `) {+object . assign(all params,queries);+ }+ } }返回allParams}辅助功能
//判断当前路径是否为tabBarconst { tabBar } = appConfigexport isTabBar =(route)= gt;tabbar . list . some(({ page path })= gt;page path = = = route);按照这个逻辑,是不是不需要区分是否是isTabBar页面,所有页面都是从queryMap获取的?目前这个问题会跟进总结,因为我还没试过,从页面实例的选项中得到的值是缺失的。所以可以先继续读取getCurrentPages的值。
方法5 EventChannel事件调度通信
我前面提到过,url参数可以用来将数据从“当前页面A”传输到打开的“页面B”。那么你希望如何让数据从打开的页面传输到当前页面呢?也可以传递url参数吗?
答案是肯定的,前提是不需要保存“A页”的状态。如果想保持“A页”的状态,需要使用navigateBack返回上一页,而这个api不支持携带url参数。
这样就可以使用页面之间的EventChannel了。
第一页
//wx . navigate to({ URL: # 39;pageB?id = 1 # 39,events: {//为指定事件添加一个侦听器,以获取从打开的页面传输到当前页面的数据acceptdatafrompendpage:function(data){ console . log(data)},},Success:function(RES){//Send data RES . event channel . emit( # 39;acceptDataFromOpenerPage # 39,{数据: # 39;测试 # 39;}) }});PageB页面
page({ onLoad:function(option){ const event channel = this . getopenereventchannel()event channel . emit( # 39;acceptDataFromOpenedPage # 39,{数据: # 39;测试 # 39;});//监听acceptDataFromOpenerPage事件,获取数据event channel( # 39;acceptDataFromOpenerPage # 39,function(data){ console . log(data)} })会不会出现数据无法监控的情况?
小程序的堆栈不超过10层。如果当前A页不是第10层,可以使用navigateTo jump保留当前页,跳转到B页,此时B页填写完毕,数据传输到A页,A页可以监控数据。
如果当前“页面A”已经是第10页,您只能使用重定向跳转到“页面b”页面。结果,当前的“页面A”不在堆栈中,而新的“页面B”在堆栈中。此时,当B页向A页传输数据时,您无法通过调用navigateBack返回目标A页,因此无法正常监控数据。
但是在我分析过的小程序中,栈中很少有10层和5层的情况。因为调用wx.navigateBack和wx.redirectTo将关闭当前页面,所以调用wx.switchTab将关闭所有其他非tabBar页面。
所以很少会出现回不到上一页监控数据的情况。如果出现这种情况,首先要考虑的不是数据监控,而是如何返回上一页。
比如在PageA页面中,先调用getCurrentPages获取页数,然后删除其他页面,再跳转到PageB页面,这样可以防止PageA调用wx.redirectTo并关闭PageA。但官方不建议开发者手动更改页面堆栈,需要谨慎。
如果有读者遇到这种情况,知道怎么解决,请告诉我,谢谢。
使用定制的事件中心EventBus
除了使用官方EventChannel,我们还可以定制一个全球EventBus事件中心。因为更灵活,在调用wx.navigateTo等API时不需要传入参数,跨平台移植性更强。
导出默认类event bus { private define event = { };//注册事件公共寄存器(event: string,CB): void {if(!this . define event[event]){(this . define event[event]=[CB]);} else { this.defineEvent[event]。推(CB);} }//调度事件公共调度(事件:string,arg?:any):void { if(this . define event[event]){ { for(let I = 0,len = this.defineEvent[event])。长度;我 ltlen++ I){ this . define event[event][I] ; this . define event[event][I](arg);} } } } } }//on监听public on(事件:string,CB): void {return this.register(事件,CB);} // off方法public off(事件:string,cb?):void { if(this . define event[event]){ if(type of(CB)= = ;未定义 ){删除this . define event[event];//表示删除所有} else {//遍历查找for (let I = 0,len = this.defineevent [event])。长度;我 ltlen++ I){ if(CB = = this . define event[event][I]){ this . define event[event][I]= null;//标记为空-防止dispath长度改变//延迟删除对应的事件SetTimeout(()= >;this . define event[事件]。拼接(I,1),0);打破;} } } } } }//once方法,监听public once(事件:string,CB):void { let once CB = arg = >;cb CB(arg);this.off(event,once CB);} this.register(event,once CB);}//清空所有事件public clean():void { this . define event = { };} } export connst event bus = new event bus();在第一页听第二页:
eventbus . on( # 39;更新 # 39;,(数据)= gtconsole . log(data));在PageB页面上分发
eventbus . dispatch( # 39;someEvent # 39,{姓名: # 39;naluduo233 # 39});本总结主要讨论如何定制微信小程序的组件,涉及两个方面:
组件声明和使用组件之间的通信。如果你用的是taro,直接按照react的语法定制组件就可以了。如果组件之间相互通信,因为taro最终会被编译成微信小程序,所以url和eventbus页面组件通信方式是适用的。后续我们会分析vant-ui weapp的一些组件源代码,看看优赞是怎么实践的。
【相关学习推荐:小程序开发教程】以上是微信小程序中自定义组件的方法的详细内容。请多关注主机参考其他相关文章!
这几篇文章你可能也喜欢:
本文由主机参考刊发,转载请注明:微信小程序中自定义组件的方法分析 https://zhujicankao.com/73808.html
评论前必须登录!
注册