摘要:引入组件假如我要在里引入组件想在页面中使用组件必须在文件里注册组件。组件的属性列表组件的方法列表组件内数据传到外部在这个组件内我定义了这个方法,每次点击一级菜单或二级菜单的时候我就用过方法把的值传到组件外部以供使用。
一、前言
如果小程序中有可复用的UI且具有一定的功能性,就可以使用自定义组件将其封装起来。(如果仅仅只需要复用UI可使用template)
下面介绍父子组件的数据传递方法,以及一个简单的组件和一个复杂的组件示例。
【由于刚开始写这篇文章的时候我还算是一个小程序的新手,自己看着官方文档研究并整理归纳的,有很多不足以及错误的地方。在经过一年的沉淀以后(虽然这一年我主要在写vue而不是小程序),我决定重新整理这篇浏览量比较大的文章,以免新手因我的文章走了弯路。】
二、父子组件传递数据的方法 1.父组件向子组件传递数据parent.wxml
parent.js
data: { name: "Peggy", age: 25 }
child.js
properties: { name: { type: String, value: "小明" }, age: Number }
父组件向子组件传值以属性的形式,子组件以properties接收,并可指定数据类型type以及默认值value。
在wxml里可直接以{{name}}的形式使用,而在js中以this.properties.name获取。
child.js
methods: { changeName() { this.triggerEvent("changeName", { name: "李四" }) } }
parent.wxml
parent.js
changeName(event) { console.log(event.detail) // { name: "李四" } }
子组件向父组件传递数据使用this.triggerEvent方法,这个方法接受3个参数:
this.triggerEvent("myevent", myEventDetail, myEventOption);
myevent为方法名,
myEventDetail是传到组件外的数据,
myEventOption为是否冒泡的选项,有三个参数可以设置:
bubbles 默认false 事件是否冒泡 composed 默认false 事件是否可以穿越组件边界 capturePhase 默认false 事件是否拥有捕获阶段
在父组件监听事件bindchangeName="changeName",在changeName方法里有一个event参数,可以从event.detail里拿到组件内部传出来的值。
三、简单的组件(计数器) 1. 组件功能介绍这个组件常见于外卖软件中,用于记录想要购买的商品的数量。初始化的时候只有一个加号,点击加号以后出现数字和减号,并最后将数字传到组件外供外部使用。
2. 创建组件首先在根目录创建components文件夹(推荐),然后创建num-controller文件夹(我取的组件名字),在这个文件夹上点击右键新建一个component,名字为index。
/components/num-controller/index.wxml
{{num}}
这段代码就是加减两个按钮和一个数字。
/components/num-controller/index.json
{ "component": true, "usingComponents": {} }
这个文件在创建component的时候会自动写入这段代码。
/components/num-controller/index.js
Component({ /** * 组件的属性列表 */ properties: { nameId: { type: String }, num: { type: Number, value: 0 }, int: { type: Number, value: 1 }, min: { type: Number, value: 0 } }, /** * 组件的初始数据 */ data: { }, /** * 组件的方法列表 */ methods: { numChange() { this.triggerEvent("numChange", { num: this.properties.num, nameId: this.properties.nameId }) }, add() { this.setData({ num: this.properties.num + this.properties.int }) this.numChange() }, sub() { this.setData({ num: this.properties.num - this.properties.int }) this.numChange() } } })
在组件内部我定义了4个属性,properties是父组件传给子组件的属性。
nameId用来标识子组件的唯一性,如果在父组件内有多个计数器,子组件想把改变的数据传给父组件时可以用到;
num代表计数器中的数字,默认为0;
int代表加减一次改变多少,默认为1;
min代表计数器的最小值,等于这个值时减号会消失,默认为0。
同时在子组件内定义了两个方法:
add点击加号触发,首先改变子组件内部的数字,同时触发numChange方法将改变的数字传到组件外部;
sub点击减号触发,首先改变子组件内部的数字,同时触发numChange方法将改变的数字传到组件外部。
假如我要在index.wxml里引入组件:
index.json
{ "usingComponents": { "num-controller": "/components/num-controller/num-controller" } }
想在页面中使用组件必须在json文件里注册组件。
index.js
Page({ data: { num1: 0, num2: 10, num3: 100 }, numChange(event) { const {num, nameId} = event.detail this.setData({ [nameId]: num }) } })
data里的num1, num2, num3是从组件外传入的num,在numChange方法里用event.detail可以拿到组件内部通过this.triggerEvent传出来的数据,然后根据业务需求做逻辑修改。
四、复杂的组件(筛选面板)这是一个二级菜单,点击左边(一级)会改变右边(二级)的展示。
1. 创建组件并引入组件内部:
/components/filter-panel/index.wxml
... ...
/components/filter-panel/index.json
{ "component": true, "usingComponents": {} }
组件外部:
假如我要在index.wxml里引入组件:
index.json
{ "usingComponents": { "filter-panel": "/components/filter-panel/index" } }
这样就成功引入组件啦~(说真的组件化做好了非常舒服,后期会省很多力气)
2.组件与外部的数据传递 (1) 固定数据渲染组件外部:
index.wxml
index.js
data: { list: [ ["附近", "地铁站"], [["不限", "1km", "2km", "3km"], ["江汉路", "积玉桥", "洪山广场", "楚河汉街", "光谷广场"]] ], active: [0, 0] },
组件内部:
/components/filter-panel/index.js
Component({ /** * 组件的属性列表 */ properties: { list: Array, active: Array }, /** * 组件的方法列表 */ methods: { ... } })
如果想从组件外向组件内传递数据,直接在外部引用时以属性的方式传入。
这里我传入了2个属性:
list是二级选择面板渲染的数据。
active是用户选择的选项数据。
到这里组件已经可以正常展示了,但是点击显示选中项还未实现。
(2) 可变数据渲染控制组件active项的是外部的数据active: [0, 0],通过组件以属性的形式传到了内部。
/components/filter-panel/index.wxml
- {{item}}
- {{item}}
/components/filter-panel/index.js
Component({ /** * 组件的属性列表 */ properties: { list: Array, active: Array }, /** * 组件的方法列表 */ methods: { changeLevel() { this.triggerEvent("changeLevel", { level1: this.properties.active[0], level2: this.properties.active[1] }) }, changeLevel1(event) { const index = event.target.dataset.index this.setData({ active: [index, 0] }) this.changeLevel() }, changeLevel2(event) { const level2 = "active[1]" const index = event.target.dataset.index this.setData({ [level2]: index }) this.changeLevel() } } })(3) 组件内数据传到外部
在这个组件内我定义了changeLevel这个方法,每次点击一级菜单或二级菜单的时候我就用过this.triggerEvent方法把active的值传到组件外部以供使用。
/components/filter-panel/index.js
methods: { changeLevel() { this.triggerEvent("changeLevel", { level1: this.properties.active[0], level2: this.properties.active[1] }) }, changeLevel1(event) { const index = event.target.dataset.index this.setData({ active: [index, 0] }) this.changeLevel() }, changeLevel2(event) { const level2 = "active[1]" const index = event.target.dataset.index this.setData({ [level2]: index }) this.changeLevel() } }五、总结
这个项目里倒是没用用到组件间的数据传递,所以只是组件和外部的传递,还算是比较简单,但是一定要思考清楚数据的变化状态。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/94409.html
摘要:自定义组件触发的时候。使用外部样式表在最上方引入文件,微信小程序的路径一个大坑,接着在引入即可。 好吧,突然发现学不完了,一下子,那就分开吧,由于时间太久,直接重新大致复习了一下 微信小程序自定义组件微信小程序支持自定义组件下方的目录showImg(https://melovemingming-1253878077.cos.ap-chengdu.myqcloud.com/blog-im...
摘要:传统的网页编程采用的三剑客来实现,在微信小程序中同样有三剑客。观察者模式不难实现,重点是如何在微信小程序中搭配其特有的生命周期来使用。交互事件传统的事件传递类型有冒泡型与捕获型,微信小程序中自然也有。 本文由作者邹永胜授权网易云社区发布。 简介为了更好的展示我们即时通讯SDK强悍的能力,网易云信IM SDK微信小程序DEMO的开发就提上了日程。用产品的话说就是: 云信 IM 小程序 S...
摘要:微信小程序的一种框架简述由于项目原因,我于两个多月前转到微信端用进行开发。事件发起组件的所有祖先组件会依次接收到事件。注意,如果用了自定义事件,则中对应的监听函数不会再执行。 wepy——微信小程序的一种框架 简述 由于项目原因,我于两个多月前转到微信端用wepy进行开发。wepy开发风格接近于 Vue.js,支持组件 Props 传值,自定义事件、组件分布式复用Mixin、Redux...
摘要:自定义组件的自定义组件,是基于微信小程序框架的组件之上,进一步自定义组合,拥有逻辑处理和样式。这样做的目的请参见微信小程序开发三宗罪和解决方案项目中通用自定义组件存放在目录,一个组件一般由三个文件组成,和分别对应微信小程序框架的和文件。 Labrador 是一个专为微信小程序开发的组件化开发框架。 特性 使用Labrador框架可以使微信开发者工具支持加载海量NPM包 支持ES6/7...
阅读 2682·2021-09-26 10:19
阅读 2135·2021-09-24 10:27
阅读 2519·2021-09-01 10:42
阅读 2301·2019-08-29 16:09
阅读 2484·2019-08-29 15:17
阅读 1447·2019-08-29 15:09
阅读 632·2019-08-29 11:14
阅读 2300·2019-08-26 13:25