VPS参考测评推荐
专注分享VPS主机优惠信息
衡天云优惠活动
荫云优惠活动
wexlayer优惠活动
最新

浅析如何自定义微信小程序组件(在小程序中使用自定义组件和模板)

主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情!
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作

如何自定义微信小程序的组件?下面的文章将为您介绍如何自定义微信小程序的组件。 希望对您有帮助!

在微信小程序的开发过程中,我们将一些页面模块封装成可能在多个页面中使用的组件,可以提高开发效率。 你可以部署一整个组件库如weui、vant等,但通常将其封装为自定义组件更可控,尽管你可能会考虑微信小程序包大小限制。

一些业务模块可以封装成组件并复用。 本文主要涵盖两个方面:

组件声明和使用。 声明和使用通信组件

微信小程序的组件体系最底层是通过小程序的基础库——Exparser组件框架来实现的,它内置于内置组件和小程序内的所有组件中。 自定义组件由 Exparser 组织和管理。

自定义组件包括以下文件以及创建页面:

index.jsonindex.wxmlindex.wxssindex.jsindex.wxs

创建选项卡组件是一个示例如下:自定义组件 json 文件中的组件字段必须设置为 true。

{ "component": true}

在js文件中,基础库提供了两个构造函数:Page和Component。 页面 对应的页面是页面根组件。 各组件对应如下:

Component({ options: { // 组件设置 addGlobalClass: true, // 指定所有以 _ 开头的数据字段为纯数据字段。 // 纯数据字段 这些不用于渲染界面。有些数据字段是未使用,可用于提高页面刷新性能。在定义选项中启用多槽支持 },properties: { vtabs: {type: Array, value: []}, }, data: { currentView: 0, },observers: { // 监控 activeTab: function( activeTab) { th Is.Scrolltabbar(ActiveTab);}},关系:{//关联子--/父组件'../vtabs[/index':{ type: 'child', // 关联的目标节点必须是链接的子节点。 函数(目标) { This.calcVtabsCotentHeight(目标) },未链接:函数(目标) {                                                                                                                                                                                                                                。 etimes: { // 组件的生命周期已创建: function() { // 当组件实例刚刚创建时 },attached : function() { // 当组件实例进入页面节点树时执行 } ,分离: function( ) { // 在当组件实例从页面节点树中删除时执行。                                                                                                                       。

当小程序启动时,构造函数会将开发者设置的属性、数据、方法和其他定义部分写入Exparser的组件注册表中。 如果该组件被其他组件引用,您可以根据这些注册信息创建自定义组件的实例。

模板文件 wxml:

样式文件:

.vtabs {}

用于外部pages 组件,您需要文件中特色页面的 json

{ "navigationBarTitleText": "Product Category", "usingComponents": { "vtabs": "../../../components/vtabs", }}

在页面初始化期间,会创建 Exparser 页面根组件的实例,所使用的其他组件也通过创建组件实例来响应(这是一个)。递归过程):

组件创建过程一般包括以下几点:

p>

根据组件的注册信息从组件创建组件节点JS对象。 原型就是这个组件。

将组件注册信息数据复制为组件数据,即this.data。

将此数据与组件 WXML 连接起来。 在此基础上,创建了Shadow Tree(组件的节点树)。 由于影子树中可能会引用其他组件,因此这会递归地触发其他组件。创作过程。

将ShadowTree加入复合树(最终组合的页面节点树)并生成缓存数据,优化组件更新性能。

触发组件的生命周期创建函数。

如果不是页面根组件,则必须根据组件节点的属性定义来设置组件的属性值。 ;

当某个组件实例在页面上可见时,该组件的附加生命周期如果Shadow Tree中还有其他组件及其生命周期函数也会一一触发。

组件通信

业务职责常常需要将大页面拆分为多个组件,并且组件之间必须发生数据通信。

代际组件通信允许全局状态管理。 这里只讨论一般的父子组件通信。

方法1 WXML数据绑定

对于父组件,组件将数据设置为子组件的指定属性。

子声明属性

Component({ property: { vtabs: {type: Array, value: []}, // 数据项格式为 `{title}` }})

调用父组件:

方法2事件

用于将数据从子组件传递到父组件,任何数据都可以传递。

要从子组件分派事件,首先将子组件的单击事件绑定到 wxml 结构。

接下来,在 js 文件中调度事件。 事件名称可以是自定义输入,第二个参数可以传递数据对象,第三个参数是事件选项。

handleClick(e) { This.triggerEvent( 'tabclick', { index }, {bubbles: false, // 事件是否冒泡 // 事件是否可以跨越组件边界。 如果为 false,则事件仅引用组件。 在节点树上触发。 // 不进入其他组件。 COMPOSITE: false, CAPTUREPHASE: FALSE // 事件是否有捕获阶段 ); }, handleChange(e) { this.triggerEvent('tabchange', {index });父组件。

方法3 selectComponent 检索组件实例对象。

您可以获得组件的实例。 调用子组件使用 selectComponent 方法来调用子组件的方法。

父组件wxml

父组件js wxml

页面({ reCalcContentHeight(index) { const GoodsContent = this.selectComponent(`#goods-content${index}`); },})

选择器是 CSS 选择器,仅支持以下语法:

ID选择器:#the-id(作者只测试了这个,其他读者可以自行测试) 类选择器(连续多个):.a[k3 ]class.another-class 子元素选择器:.the-parent > .the-子后代选择器:.the-ancestor .the-descendant 自定义组件之间的后代选择器:.the-ancestor >>> .the-descendant 组合多个选择器:#a[ k3]node, .some-other-nodes

方法4 URL参数通信

In 电商/物流等微信小程序有这样的用户故事,其中有“订单页面A”和“商品信息页面B”,在“订单页面A”输入基本信息时,输入详细信息。要进入,您必须向下钻取至详细信息页面 B。 例如,在快递订单页面,您需要向下钻取到货件信息页面,输入详细信息,然后返回上一页。 您需要从“订单页面 A”深入到“产品页面 B”并回显“产品页面 B”中的数据。

一个微信小程序由一个App()实例和多个Page()组成。 小程序框架以栈的方式维护页面(最多10个),并提供以下API: 跳转至页面。 页面根目录是:

wx.navigateTo(只能跳转到栈内页面))

wx.redirectTo(跳转到栈外新页面并替换当前页面)

wx.navigateBack(返回上一页,不能携带)参数)

wx.switchTab(切换标签页.URL (不支持参数)

wx.reLaunch(重启小程序)

可以简单封装。 JumpTo跳转函数及传递参数:

export function JumpTo(url, options) { const BaseUrl = url.split('?')[0]; // 如果URL有参数,也挂载有需要。 转到选项 if (url.indexof('?') !== -1) {const { query } =solveUrl(url); Object.assign(options, query, options); // 选项具有最高优先级 } cosnt queryString = objectEntries(options) .filter(item => item[1] || item [0 ] === 0) // 除了数字0之外的所有其他非值都会被过滤 .map( ([key, value]) => { if (typeof value ===“对象”) {                                                                         我 ey} = ${值} `;})。 join ('&'); if (queryString) {// 需要组装参数 url =`${bas eUrl}?${queryString}`。 ;== 'navigateTo' && 页数 {                                                                                       To({ url, url, failed: () => { wx.switch ({ url:baseUrl }); }

jumpTo 辅助函数:

export constsolveSearch = search => { const requests = {}; = ''] = param.split('='); 查询[key] = 值 });export constsolveUrl = (url) => { if (url.indexOf('?') === -1) { // 不带参数的 URL return { requests: {} , Pay: url }} const [page, search] = url.split ( '?'); Const QUERIES = Resolvesearch (搜索);n { page, requests };};

将数据传递到“订单页面 A”:

jumpTo({ url: 'pages/c onsignment/index', sender: {                                                                   ;URL参数:

const sender = JSON.parse(getParam('sender') || '{}');

url参数获取辅助函数

//导出函数返回当前页面getCurrentPage () { const pageStack = wx.getCurrentPages(); const lastIndex = pageStack.length - 1; const currentPage = pageStack[lastIndex]; currentPage;} //获取页面URL参数 export function getParams() { const currentPage = getCurrentPage() || const {route, options } = currentPage; o bjectEntries(options);entries.forEach( , value]) =>                                                                                                                                                                                                                      ); 为什么路由API不支持参数传递?

微信 虽然小程序官方文档没有规定页面可以保留的参数长度,但参数过长仍然可能存在被截断的风险。

您可以使用全局数据记录参数值,同时解决URL参数过长或路由API不支持参数的问题。

// global-data.js// switchTab不支持持久化参数,所以应该考虑使用全局数据存储 // 无论是否switchTab,首先挂载数据到 const queryMap = { page: ' ', query: {}};

更新跳转函数

导出函数 JumpTo(url, options) { // ... Object.assign(queryMap , { page:baseUrl, 查询:可选 }); // ... if (jumpType === 'switchTab') { wx.switchTab({ url:baseUrl }); else if (jumpType === 'navigateTo' && pageCount { 。wx.navigateTo({ url, failure: () => { wx.switch({ url:baseUrl }); } }); }}

url参数获取辅助函数

// 获取页面URL参数导出function getParams() { const currentPage = getCurrentPage() {}; const allParams = {}; const {root, options} = 当前页面; (可选) { const Entry = objectEntries(可选); events.forEach(([key, value]) => { allParams[key] = de codeURIComponent(value); ); // 但是 if + (page ==                                                                ; 查询);+                                                                                ;否 是 tabBarconst { tabBar} = appConfig;export isTabBar = (route) => tabBar.list.some(({ pagePath })) => pagePath === Route);

按照这个逻辑,这个都是存在的。 无需区分 isTabBar 和 page。 是否所有页面都从 queryMap 检索?我正在进一步调查此问题,然后再做出任何结论,因为我还没有尝试过,并且从页面实例选项检索的值丢失。 所以可以先继续读取getCurrentPages的值。

方法五EventChannel事件分发通信

前面我们提到可以使用URL参数将数据从“当前页面A”传输到打开的“页面B”。 。 那么如果我们想要将数据从打开的页面传输到当前页面呢?是否可以传递 URL 参数?

我需要保存“页面 A”的状态除非,答案是肯定的? 。 如果想保持“A页”的状态,则需要使用navigateBack返回上一页。 该API不支持保留URL参数。

此时可以使用页面间事件通信通道EventChannel。

pageA Page

// wx.navigateTo({ url: 'pageB?id=1', events: { // 添加指定事件的监听,导航到打开的页面获取数据从页面发送到当前页面acceptDataFromOpenedPage: function (data) {console.log(data)},}, Success: Function (res) {//Eventchannel数据到打开的页面res.eve 发送ntChannel.emit('acceptDataFromOpenerPage', { data: 'test' }) }});

pageB Page

Page({ onLoad: function(option){ consteventChannel = this.getOpenerEventChannel()eventChannel.emit ( 'acceptDataFromOpenedPage', {data: '测试'}); 事件通过 eventChannel.on('acceptDataFromOpenerPage', function(data) { console.log(data) }) }}) 检索从上一个页面发送到当前页面的数据

是否会出现这样的情况?数据无法监控? ?

小程序栈不超过10层。 如果当前“Page A”不是第10层,可以使用navigateTo跳转到,保持当前页面,跳转到“Page B”。 此时,在“页面B”上完成录入后,数据被传递到“页面A”,“页面A”可以监控数据。

如果当前“Page A”已经是第10页,则只能使用redirectTo跳转到“PageB”页面。 结果,当前的“页面A”被从堆栈中弹出,并且新的“页面B”被压入堆栈。 ,“Page B”正在向“Page A”传递数据,无法成功监听数据,因为无法通过调用navigateBack返回到目标“Page A”。

但是,在我分析过的小程序中,栈很少有10层的。 另外,调用wx.navigateBack和wx.redirectTo会通过调用wx.swit来关闭当前页面,所以层数也不多。chTab 关闭所有其他非 tabBar 页面。

因此,您不太可能无法返回上一页来监控您的数据。 发生这种情况时,首先要考虑的不是如何监控您的数据,而是如何确保您的数据得到保留。

例如,在“PageA”页面上,首先调用getCurrentPages获取页数,然后在跳转到“PageB”页面之前删除其他页面,避免调用wx. 由于 .redirectTo 而关闭。 “A页”。 但是,请注意,官方并不鼓励开发人员手动修改页面堆栈。

如果我们的读者遇到过这种情况并且知道如何解决,请告诉我们。 谢谢。

使用自定义EventBus事件中心

除了使用官方提供的EventChannel之外,还可以自定义全局EventBus事件中心。 这样更加灵活,无需在 wx.navigateTo 等 API 调用上传递参数,并且使向多个平台的迁移更加强大。

导出默认类EventBus {privatedefineEvent={}; // 注册事件 public register(event:string, cb): void { if(!this.defineEvent[event]) { (this.defineEvent[event] = [ cb]); } else { this.defineEvent[event].push(cb); // 调度事件 publicdispatch(event:string,arg?:any): void { if(this.defineEvent[event]) {{ for(let i=0, len = this.defineEvent[event].leni this.defineEvent[event].splice(i, 1), 0); // ONCE方法,监听端口一次 (event: string, cb): void {let Oncecb = arg = > { cb && cb(arg); this.off(event, oneCb); this.register(event, oneCb); 清除所有事件 public clean(): void { this.defineEvent = {} }}export connsteventBus = new EventBus();

页面监视器中的PageA:

eventBus.on('update' , (data) => console.log(data));

Page B 页面调度

eventBus.dispatch('someEvent', { name: 'naluduo233'}); 概述

本文主要讲解如何自定义微信小程序的组件。 它包括两个方面:

组件声明和使用组件之间的通信

如果您使用 taro,则可以直接自定义组件。 反应语法。 关于组件通信,由于 taro 最终编译成微信小程序,所以采用了 URL 和事件总线的页面组件通信方式。 返回我会继续分析vant-ui weapp的一些组件的源码,看看有赞是如何实践的。

感谢您的阅读。 有错误的地方请指出。

【相关学习推荐:小程序开发教程】

下载微信小程序。

微信是一款支持手机发送的移动通讯软件。 网络语音消息、视频、照片、文本。 微信带来了全新的移动通信体验,您可以单独或群组聊天,还可以根据您的地理位置查找附近的人。 有需要的朋友,请快来保存您的下载体验吧!

这几篇文章你可能也喜欢:

本文由主机参考刊发,转载请注明:浅析如何自定义微信小程序组件(在小程序中使用自定义组件和模板) https://zhujicankao.com/141218.html

【腾讯云】领8888元采购礼包,抢爆款云服务器 每月 9元起,个人开发者加享折上折!
打赏
转载请注明原文链接:主机参考 » 浅析如何自定义微信小程序组件(在小程序中使用自定义组件和模板)
主机参考仅做资料收集,不对商家任何信息及交易做信用担保,购买前请注意风险,有交易纠纷请自行解决!请查阅:特别声明

评论 抢沙发

评论前必须登录!