组件
目录1. 组件基础
1.1 组件的创建与引用
-
创建组件
- 在项目根目录中创建components→comp1文件夹
- 在文件夹上右键,点击"新建Component"自动生成所需文件
Component({ properties: {}, data: {}, methods: {} })
-
引用组件
-
在页面的
.json
配置文件中引用组件的方式,叫做"局部引用" -
在
app.json
全局配置文件中引用组件的方式,叫做"全局引用" -
示例代码
- JSON
{ "usingComponents":{ "my-test1": "/components/test1/test1" } }
- WXML
<mt-test1></mt-test1>
-
-
组件和页面的区别
- 组件的json文件中需要声明
"component":true
属性 - 组件的js文件中调用的是
Component()
函数 - 组件的事件处理函数需要定义到methods节点中
- 组件的json文件中需要声明
1.2 properties属性
(data和methods与vue基本一致不做过多介绍)
-
properties是组件的对外属性,用来接收外界传递到组件中的数据
小程序是允许在组件中修改properties的
Component({ properties: { //完整形式,需要设置被传递值的类型和默认值 max:{ type: Number, value: 10 }, //如果不设置默认值可以简写 max: Number }, })
1.3 数据监听
-
小程序中使用
observers
来监听和响应任何属性和数据字段的变化Component({ observers:{ '数据A, 数据B': function(数据A的新值,字段B的新值){ //... } } })
-
监听对象属性的变化
小程序的监视属性自带深度监视,所以可以直接监视对象中属性的变化
Component({ obervers:{ '对象.属性A, 对象.属性B': function(属性A的新值,属性B的新值){ //... } } })
-
监听对象中所有属性的变化
如果某个对象中需要被监听的属性太多,为了方便,可以使用通配符
**
来监听对象中所有属性的变化//一次性监视rgb对象中的r,g,b属性 observes:{ 'rgb.**': function(obj){ this.setData({ fullColor: `${obj.r},${obj.g},${obj.b}` }) } }
2. 常用组件
- 一共有9种组件:视图容器、基础内容、表单组件、导航组件、媒体组件、map地图组件、canvas画布组件、开放能力、无障碍访问
2.1 视图容器
-
view
- 普通视图区域,类似于HTML中的div,是一个块级元素,常用来实现页面布局效果
-
scroll-view
- 可滚动的视图区域,常用来实现滚动列表效果
- 属性
scroll-y
:允许纵向滚动(使用时必须给scroll-view一个固定高度)scroll-x
:允许横向滚动
<scroll-view class="container1" scroll-y> <view>A</view> <view>B</view> <view>C</view> </scroll-view>
-
swiper和swiper-item
- 轮播图容器区间和轮播图item组件
- 更多属性请参考API
<swiper> <swiper-item> <view class="item">A</view> </swiper-item> <swiper-item> <view class="item">B</view> </swiper-item> <swiper-item> <view class="item">C</view> </swiper-item> </swiper>
2.2 内容
-
text
- 文本组件,类似于HTML中的span标签,是一个行内元素
- 添加selectable属性支持长按选中效果
<view> <text selectable>135000000</text> </view>
-
rich-text
- 富文本组件,通过组件的nodes属性节点,把HTML字符串渲染为对应的UI结构
<rich-text nodes="<h1 style='color:red;'>标题</h1>"></rich-text>
2.3 navigator
navigator标签被用于声明式路由导航
- url表示要跳转的页面地址,必须以
/
开头 - open-type表示跳转的方式,如果跳转的页面为tabBar页面,该属性必须为
switchTab
<navigator url="/pages/info/info">导航到info页面</navigator>
<navigator url="/pages/message/message" open-type="switchTab">
导航到消息页面
</navigator>
如果要后退到上一页面或多级页面,则需要指定open-type属性和delta属性
- open-type的值必须是
navigateBack
,表示要进行后退导航 - delta的值必须是数字,表示要后退的层级数
<navigator open-type="navigateBack" delta="1">后退</navigator>
编程式路由导航
调用wx.switchTab(Object object)
方法,可以跳转到tabBar页面
调用wx.navigateTo(Object object)
方法,可以跳转到非tabBar页面s
其中Object参数对象的属性列表如下
属性 | 说明 |
---|---|
url | 需要跳转的tabBar页面的路径,路径后不能带参数 |
success | 接口调用成功的回调函数 |
fail | 接口调用失败的回调函数 |
complete | 接口调用结束的回调函数(无论调用结果如何都会执行) |
-
示例代码
- WXML
<button bind:tap="gotoMessage">跳转到消息页面</button>
- JS
//导航到tabBar页面 gotoMessage(){ wx.switchTab({ url:'/pages/message/message' }) } //导航到非tabBar页面 gotoInfo(){ wx.navigateTo({ url:'/pages/info/info' }) }
如果要后退到上一页面或多级页面,需要调用wx.navigateBack(Object object)
方法,可以返回上一页面或多级页面。
其中Object参数对象可选的属性列表如下:
属性 | 说明 |
---|---|
delta | 返回的页面数,如delta大于现有页面数,则返回到首页 |
success | 接口调用成功的回调函数 |
fail | 接口调用失败的回调函数 |
complete | 接口调用结束的回调函数(无论调用结果如何都会执行) |
-
示例代码
- WXML
<button bind:tap="gotoBack">后退</button>
- JS
goBack(){ wx.navigateBack({ wx.navigateBack() }) }
2.4 其它组件
-
button
-
按钮组件,功能比HTML中的button丰富,通过open-type属性可以调用微信提供的各种功能(客服、转发等)
-
属性
type
:指定按钮颜色类型size
:调整按钮大小plain
:按钮是否镂空
<button>普通按钮</button> <button type="primary">普通按钮</button> <button type="warn">警告按钮</button> <button type="primary" size="mini">小尺寸按钮</button> <button type="warn" plain>镂空按钮</button>
-
-
image
-
图片组件,默认宽度为300px,高度为240px
<image src="/images/1.png" mode="heightFix"></image>
-
image的mode属性可以用于设置图片剪裁、缩放模式
值 说明 aspectFit 保持图片宽高比缩放,保证长短边都显示完整 aspectFill 保持图片宽高比缩放,保证短边显示完整,长边被截取 scaleToFill 缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 widthFix 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变 top/bottom/center/left/right 裁剪模式,不缩放图片,只显示图片的顶/底/中/左/右部区域 top left/right 裁剪模式,不缩放图片,只显示图片的左/右上边区域 bottom left/right 裁剪模式,不缩放图片,只显示图片的左/右下边区域
-
3. 组件间通信
3.1 属性绑定
-
属性绑定用于父向子传值,且只能传递普通类型的数据,无法将方法传递给子组件
-
示例代码
- 父组件
<my-test count="{{count}}"></my-test>
- 子组件
<text>{{count}}</text> <script> properties: { count: Number } </script>
3.2 事件绑定
-
事件绑定用于实现子向父传值,可以传递任何类型数据,操作步骤如下;
- 在父组件的js中定义一个函数,该函数即将通过自定义事件的形式,传递给子组件
- 在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
- 在子组件的js中,通过调用
this.triggerEvent('自定义事件名称',{参数对象})
,将数据发送到父组件 - 在父组件的js中,通过
e.detail
获取到子组件传递过来的数据
-
示例代码
- 父组件
<my-test count="{{count}}" bind:gogogo="gogogoCount"></my-test> <script> syncCount(e){ this.setData({ count: e.detail.value }) } </script>
- 子组件
<text>{{count}}</text> <button bind:tap="addCount">+1</button> <script> addCount(){ this.setData({ count:this.properties.count + 1 }) this.triggerEvent('sync',{value:this.properties.count}) } </script>
3.3 获取组件实例
-
可在父组件中调用
this.selectComponent("id或class选择器")
,获取子组件的实例对象,从而直接访问子组件的任意数据和方法 -
示例代码
- 父组件
<my-test count="{{count}}" bind:gogogo="gogogoCount" class="customA"></my-test> <button bind:tap="getChild">获取子组件实例</button> <script> getChild(){ //class选择器 const child = this.selectComponent('.customA') //调用子组件中的setData方法 child.setData({ count:child.properties.count+1 }) child.addCount() } </script>
3.4 插槽
默认插槽
-
在自定义组件的wxml结构中可以提供一个
<slot>
节点,即插槽,用于承载组件使用者提供的wxml结构(微信小程序不支持作用域插槽) -
默认情况下,每个自定义组件中只允许使用一个
<slot>
进行占位,如果需要使用多个插槽,需要在组件的js文件中开启如下配置:Component({ options:{ multipleSlots: true //开启多插槽支持 } })
-
示例代码
- 父组件
<coponent-tag-name> <view>插入到组件slot中的内容</view> </coponent-tag-name>
- 子组件
<view class="wrapper"> <view>这里是组件的内部节点</view> <!--对于不确定的内容就使用slot进行占位,具体内容由使用者决定--> <slot></slot> </view>
具名插槽
-
可以在组件的wxml中使用多个slot标签,并以不同的name来区分不同的插槽
-
示例代码
- 父组件
<my-test> <view slot="before">通过插槽填充的内容1</view> <view slot="after">通过插槽填充的内容2</view> </my-test>
- 子组件
<view class="wrapper"> <slot name="before"></slot> <slot name="after"></slot> </view>
4. behaviors
-
behaviors是小程序中,用于实现组件间代码共享的特性,类似于Vue.js中的mixin
-
每个behavior可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的内容会被合并到组件中。每个组件可以引用多个behavior,behavior之间也可以互相引用
-
示例代码
创建behavior
//Behavior()创建实例对象 //module.exports对外暴露 module.exports = Behavior({ properties:{}, data:{username:'zs'}, methods:{} })
导入并使用behavior
//使用require导入需要的自定义behavior模块 const myBehavior = require("../../behaviors/my-behavior") Component({ //挂载 behaviors:[myBehavior] })