Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >微信小程序组件化编程和实践(上)

微信小程序组件化编程和实践(上)

原创
作者头像
疯狂的小程序
发布于 2018-01-25 09:03:17
发布于 2018-01-25 09:03:17
2K00
代码可运行
举报
文章被收录于专栏:疯狂的小程序疯狂的小程序
运行总次数:0
代码可运行

从小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程。查看自己使用的小程序基础库版本,可以通过在开发者工具右侧点击详情查看:

最基本的组件

小程序的组件,其实就是一个目录,该目录需要包含4个文件:

  1. xxx.json
  2. xxx.wxml
  3. xxx.wxss
  4. xxx.js

声明一个组件

首先需要在 json 文件中进行自定义组件声明(将 component 字段设为 true 可这一组文件设为自定义组件)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "component": true
}

其次,在要引入组件的页面的json文件内,进行引用声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "usingComponents": {
    //自定义的组件名称     : 组件路径,注意是相对路径,不能是绝对路径  
    "component-tag-name": "path/to/the/custom/component"
  }
}

这样,在主页面就可以使用了。

相比于vue的组件引入,小程序的方案更简洁。vue组件引入是需要 import 之后,同时在 components 里面注册,而小程序的组件只需要在 .json 里面注册,就可以在 wxml 里面使用。

使用slot

和vue 相同,小程序也有slot概念。

单一slot

在组件模板中可以提供一个 <slot> 节点,用于承载组件引用时提供的子节点。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 主页面内,<addlike>是组件
<addlike item="item" my_properties="sssss">
    <text>我是被slot插入的文本</text>
</addlike>
 
// addlike 组件
<view class="container">
    <view>hello, 这里是组件</view>
    <view>hello, {{my_properties}}</view>
    <slot></slot>
</view>
 
// 渲染后
<view class="container">
    <view>hello, 这里是组件</view>
    <view>hello, {{my_properties}}</view>
    <text>我是被slot插入的文本</text>
</view>

多个slot

如果需要在组件内使用多个slot, 需要在组件js中声明启用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: { /* ... */ },
  methods: { /* ... */ }
})

使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 主页面
<addlike item="item" my_properties="sssss">
    // 在普通的元素上加入 slot 属性,指定slotname, 就可以变成子元素的slot了
    <text slot="slot1">我是被slot1插入的文本</text>
    <text slot="slot2">我是被slot2插入的文本</text>
</addlike>
 
// 子页面
<view class="container">
    <view>hello, 这里是组件</view>
    <view>hello, {{my_properties}}</view>
    <slot name="slot1"></slot>
    <slot name="slot2"></slot>
</view>

Component构造器

 刚才我们说了,一个组件内应该包括js,  wxml, wxss, json 四个文件。wxml 相当于是 HTML,wxss 相当于是 css, 那么js 里面应该写什么呢?

微信官方提供的案例中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Component({
 
  behaviors: [],
 
  properties: {
   
  },
  data: {}, // 私有数据,可用于模版渲染
 
  // 生命周期函数,可以为函数,或一个在methods段中定义的方法名
  attached: function(){},
  moved: function(){},
  detached: function(){},
 
  methods: {
    onMyButtonTap: function(){
     
    },
    _myPrivateMethod: function(){
     
    },
    _propertyChange: function(newVal, oldVal) {
 
    }
  }
})

里面调用了一个Component构造器。Component构造器可用于定义组件,调用Component构造器时可以指定组件的属性、数据、方法等。具体 Component里面可以放什么东西,如下所示:

组件与数据通信

组件化必然要涉及到数据的通信,为了解决数据在组件间的维护问题,vue, react,angular 有不同的解决方案。而小程序的解决方案则简洁很多。

主页面传入数据到组件

properties相当于vue的props,是传入外部数据的入口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 主页面使用组件
<a add_like="{{add_like}}">
</a>
 
// 组件a.js 内
Component({
    properties:{
        add_like:{
            type:Array,
            value:[],
            observer:function(){
                
            }
        }
    }
})

注意: 传入的数据,不管是简单数据类型,还是引用类型,都如同值复制一样(和红宝书里面描述js函数参数传入是值复制还不一样,红宝书里面的意思是:简单数据类型直接复制数值,引用类型复制引用,也就是说在函数内修改参数对象的属性,会影响到函数外对象的属性)。

如果是Vue的props, 则可以通过 .sync 来同步,而在小程序子组件里面,调用this.setData()修改父组件内的数据,不会影响到父组件里面的数据, 也就是说,子组件property的修改,仿佛和父组件没有任何关系。那么,如果是在子组件内修改父组件的数据,甚至是修改兄弟组件内的数据,有没有简单的方法呢?下面会有讲到

组件传出数据到主页面

和vue类似,组件间交互的主要形式是自定义事件。

组件通过 this.triggerEvent() 触发自定义事件,主页面在组件上 bind:component_method="main_page_mehod" 来接收自定义事件。

其中,this.triggerEvent() 方法接收自定义事件名称外,还接收两个对象,eventDetail 和 eventOptions

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 子组件触发自定义事件
ontap () {
    // 所有要带到主页面的数据,都装在eventDetail里面
	var eventDetail = {
		name:'sssssssss',
		test:[1,2,3]
	}
	// 触发事件的选项 bubbles是否冒泡,composed是否可穿越组件边界,capturePhase 是否有捕获阶段
	var eventOption = {
		composed: true
	}
	this.triggerEvent('click_btn', eventDetail, eventOption)
}
 
// 主页面里面
main_page_ontap (eventDetail) {
    console.log(eventDetail)
    // eventDetail
    // changedTouches
    // currentTarget
    // target
    // type
    // ……
    // detail   哈哈,所有的子组件的数据,都通过该参数的detail属性暴露出来
}

组件之间数据通信

和vue提出的vuex的解决方案不同,小程序的组件间的通讯简单小巧。你可以和主页面与组件通讯一样,使用自定义事件来进行通讯,当然更简单方便的方法,是使用小程序提供的relations.

relations 是Component 构造函数中的一个属性,只要两个组件的relations 属性产生关联,他们两个之间就可以捕获到对方,并且可以相互访问,修改对方的属性,如同修改自己的属性一样。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Component({
   relations:{
    './path_to_b': {                 // './path_to_b'是对方组件的相对路径
        type: 'child',               //  type可选择两组:parent和child、ancestor和descendant
        linked:function(target){  }  // 钩子函数,在组件linked时候被调用 target是组件的实例,
        linkChanged: function(target){}
        unlinked: function(target){}
        }
    },
})

比如说,有两个组件如代码所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 组件a slot 包含了组件b
<a>
    <b></b>
</a>

他们之间的关系如下图所示:

两个组件捕获到对方组件的实例,是通过 this.getRelationNodes('./path_to_a')方法。既然获取到了对方组件的实例,那么就可以访问到对方组件上的data, 也可以设置对方组件上的data, 但是不能调用对方组件上的方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 在a 组件中
Component({
    relations:{
        './path_to_b': {
            type: 'child',
            linked:function(target){  }  // target是组件b的实例,
            linkChanged: function(target){}
            unlinked: function(target){}
        }
    },
    methods:{
        test () {
            var nodes = this.getRelationNodes('./path_to_b')
            var component_b = nodes[0];
            
            // 获取到b组件的数据
            console.log(component_b.data.name)
            
            // 设置父组件的数据
            // 这样的设置是无效的
            this.setData({
                component_b.data.name:'ss'
            })
            // 需要调用对方组件的setData()方法来设置
            component_b.setData({
                name:'ss'
            })
        }
    }
})
 
// 在b 组件里面
Component({
    relations:{
        './path_to_a': {                      //注意!必须双方组件都声明relations属性
            type:'parent'
        }
    },
    data: {
        name: 'dudu'
    }
})

注意:1. 主页面使用组件的时候,不能有数字,比如说 <component_sub1> 或 <component_sub_1>,可以在主页面的json 里面设置一个新名字

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "usingComponents":{
        "test_component_subb": "../../../components/test_component_sub2/test_component_sub2"
    }
}

2. relations 里面的路径,比如说这里:

是对方组件真实的相对路径,而不是组件间的逻辑路径。

3. 如果relations 没有关联,那么 this.getRelationNodes 是获取不到对方组件的

4. 本组件无法获取本组件的实例,使用this.getRelatonsNodes('./ path_to_self ') 会返回一个null

4. type 可以选择的 parent 、 child 、 ancestor 、 descendant 

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
微信小程序组件化开发框架WePY
compilers: compilers为1.3.1版本之后的功能,如果需要使用其它语法,请先配置compilers,然后再安装相应的compilers。目前支持wepy-compiler-less, wepy-compiler-postcss,wepy-compiler-sass、wepy-compiler-babel、wepy-compiler-pug,其他compiler持续开发中......
达达前端
2019/07/03
1.4K0
微信小程序组件化开发框架WePY
微信小程序组件化编程和实践(下)
现在我们已经可以做到了两个组件之间的数据传递,那么如何在多个组件间传递数据呢?
疯狂的小程序
2018/01/25
2K0
微信-小程序开发基础知识笔记
一个 mut-bind 触发后,如果事件冒泡到其他节点上,其他节点上的 mut-bind 绑定函数不会被触发,但 bind 绑定函数和 catch 绑定函数依旧会被触发。
yuezhongbao
2019/11/27
9760
微信小程序 页面与自定义组件数据通信
说明:页面通过my-property讲example字符串传递给自定义组件,同样也可以使用数据绑定的方法
天天_哥
2018/11/11
3.3K0
微信小程序 页面与自定义组件数据通信
【愚公系列】《微信小程序与云开发从入门到实践》030-关于自定义组件的高级用法
在微信小程序的开发中,自定义组件是实现灵活、可复用代码的重要工具。随着小程序生态的不断发展,开发者对于组件的需求也日益增长,从基础的组件使用到高级的技巧与模式,掌握自定义组件的高级用法已成为提升开发效率和用户体验的关键所在。
愚公搬代码
2025/01/21
3020
小程序 | 11-组件化
自定义组件由 json、wxml、wxss、js 四个文件组成,我们通常是在根目录下创建一个文件夹——components,在该文件夹中存放我们自定义的公共组件。
CnPeng
2021/05/17
2.5K0
小程序 | 11-组件化
【愚公系列】2022年10月 微信小程序-优购电商项目-自定义组件
组件(Component)是对数据和方法的简单封装。组件可以有自己的属性和方法。属性是组件数据的简单访问者。方法则是组件的一些简单而可见的功能。使用组件可以实现拖放式编程、快速的属性处理以及真正的面向对象的设计。
愚公搬代码
2022/11/12
2880
【愚公系列】2022年10月 微信小程序-优购电商项目-自定义组件
高效开发必备!小程序组件复用的实用技巧
嘿,各位开发小伙伴们👨‍💻👩‍💻!在开发支付宝小程序的奇妙世界里,你是不是经常被重复劳动搞得焦头烂额呢🧐?今天,小编就来给大家支支招,分享超实用的支付宝小程序组件复用技巧,让你的开发效率蹭蹭往上涨📈,告别那些让人头疼的重复工作~
小白的大数据之旅
2025/04/24
1240
高效开发必备!小程序组件复用的实用技巧
微信小程序自定义组件
微信小程序自定义组件 一. 创建自定义组件 类似于页面,一个自定义组件由 json wxml wxss js 4个文件组成 二.组件声明 首先需要在自定义组件所在的 json 文件中进行自定义组件声明 { "component": true } 三.编辑组件 同时,还要在 wxml 文件中编写组件模板,在 wxss 文件中加入组件样式 wxml与xcss和普通页面设置差不多 wxml <!-- 这是自定义组件的内部WXML结构 --> <view class="inner"> {{innerText
小小咸鱼YwY
2020/06/19
8420
微信小程序 父子组件传值通信
微信小程序父组件往子组件传值: 父:<getCode phone="{ {phone}}" bind:myevent="onGetCode"></getCode> 通过phone=”{ {phone}}”传向子组件 子:
全栈程序员站长
2022/08/29
1.2K0
小程序自定义modal弹窗封装实现
小程序官方提供了 wx.showModal 方法,但样式比较固定,不能满足多元化需求,自定义势在必行~
solocoder
2022/04/06
4.1K2
小程序自定义modal弹窗封装实现
【博客同步】小程序开发总结01 - 模块化开发流程规范
H5 的开发涉及开发工具、前端框架、模块管理工具、任务管理工具、UI库、接口调用工具、各种浏览器运行环境等,尽管H5丰富的开发环境给了开发者更加灵活的配置方案,但增加了环境配置的成本,而开发微信小程序,由于微信团队提供了开发者工具,并且规范了开发标准,前端常见的HTML、CSS变成了微信自定义的WXML、WXSS,官方文档中都有明确的使用介绍,开发者无需关心各种环境的配置,专注于开发业务逻辑即可。
CS逍遥剑仙
2025/03/17
1830
【博客同步】小程序开发总结01 - 模块化开发流程规范
【愚公系列】2022年02月 微信小程序-Component组件的通信与事件
事件系统是组件间通信的主要方式之一。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。
愚公搬代码
2022/02/28
8620
微信小程序组件调用和传值
微信小程序像Vue和React一样赋于了组件的开发能力,支持组件的调用和传值,同时由于小程序上传时限制在2MB以内,对于稍微大一点的小程序组件的使用就特别重要了,下面给大家介绍下小程序的组件用法。
越陌度阡
2020/11/26
1.7K0
微信小程序自定义组件
其中,components为组件目录,nodemodules为模块目录,pages为小程序的页面目录,utils为一些基础功能的封装。好比安装的第三方百度统计功能在此。
mySoul
2018/09/15
2.8K0
小程序父子组件传参_微信小程序修改全局变量
点击原创或者分类虽然样式如首页一样变化,但是其父组件的最终isActive的值并未发生改变,但是样式发生改变是因为拿取的是Component>里面的properties中的tabs,你点击下去的时候一样拿取tabs数组,所以不会报错。因此子组件必须通过方法进行修改父组件中的isActive的值,方法如下:
全栈程序员站长
2022/10/03
1.3K0
小程序父子组件传参_微信小程序修改全局变量
微信小程序项目实战
微信小程序开发设置的背景图片不显示,这是由于:background-image 只能用网络url或者base64图片编码 ,本地图片只能用 image标签src属性才行。当然 image标签src属性也可以使用网络url或者base64图片编码。
生南星
2020/04/26
2.2K0
[猫头虎分享21天微信小程序基础入门教程] 第12天:小程序的自定义组件开发
大家好,我是猫头虎,一名全栈软件工程师。今天我们继续微信小程序的学习,重点了解如何开发自定义组件。自定义组件可以提高代码的复用性和模块化程度,使开发更加高效和灵活。🚀
猫头虎
2024/05/26
1750
小程序-实现自定义组件以及自定义组件间的通信
对于组件的封装,在小程序当中对于多个页面的复用有着重要的作用,小程序中注册的每个页面都是独立的
itclanCoder
2020/11/09
2.9K0
小程序-实现自定义组件以及自定义组件间的通信
小程序:子组件父组件数值互相传递
<view style='border:2px solid gray;'> <view style='text-align:center;'>我是组件B</view> <view>A中传入的参数:{{paramAtoB}}</view> </view> 总结: A组件向B组件传参,实际上就是在A组件中引入B组件的时候,带上一个属性paramAtoB,并且给其赋值,然后B组件通过这个属性名称paramAtoB,获取其值
黄啊码
2021/09/26
5070
推荐阅读
相关推荐
微信小程序组件化开发框架WePY
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验