小程序组件+弹性盒子+表单组件+自定义组件

小程序组件

小程序组件–视图容器

什么是组件?

  • 组件是视图层的基本组成单元。

组件自带一些功能与微信风格的样式。
一个组件通常包括开始标签和结束标签,属性用来修饰这个组件,内容在两个标签之内。

注意:所有组件与属性都是小写,以连字符-连接

  • 组件的属性

    • 所有组件都有如下的属性:
      id,class,style,hidden(组件是否显示),data-(自定义属性),bind/catch(事件绑定)*

组件分类

小程序中,基础组件分为了七大类:视图容器、基础内容、表单组件、导航、多媒体、地图、画布。

在小程序中,通过使用组件可以少写很多代码
关于组件的具体用法,最好的参考资料就是官方文档:
https://developers.weixin.qq.com/miniprogram/dev/component/

视图容器(View Container):

在这里插入图片描述

  • view标签:基础标签,类似H5中的div,块级标签;view有两种布局方式,block(默认)及flex
  • scroll-view:滚动视图,分为水平滚动和垂直滚动。注意滚动视图垂直滚动时一定要设置高度否则的话scroll-view不会生效。
  • swiper:滑动视图容器,多用于滑动广告图
  • movable-view:可移动区域,这个标签的实现效果多为,在某个区域里面可以进行拖动,缩放等操作
  • cover-view:多用于原生组件video,canvas,camera等标签内,作用是覆盖这些原生标签,因为这些原生标签的层级默认高于任何一个原生标签的层级且不受z-index的控制;同时,现在cover-view只支持嵌套cover-view、cover-image,可在cover-view中使用button(嵌套其他标签可能不报错,但是真机调试一定不行的)。

view

  • 微信小程序 View 支持两种布局方式:Block (块级)和 Flex(弹性盒子)
  • 所有 View 默认都是 block
  • 要使用 flex 布局的话需要显式的声明:
  • display:flex;
  • flex 布局可横向布局和竖向布局,要设置属性 flex-direction ,它有4个可选值:
  • row:从左到右的水平方向为主轴
  • row-reverse:从右到左的水平方向为主轴
  • column:从上到下的垂直方向为主轴
  • column-reverse:从下到上的垂直方向为主轴

flex布局(弹性盒子布局)要设置元素在横向上的布局方向,需要设置 justify-content 属性,它有5个值可选:

  • flex-start:主轴起点对齐(默认值)
  • flex-end:主轴结束点对齐
  • center:在主轴中居中对齐
  • space-between:两端对齐,除了两端的子元素分别靠向两端的容器之外,其他子元素之间的间隔都相等
  • space-around:每个子元素之间的距离相等,两端的子元素距离容器的距离也和其它子元素之间的距离相同

flex布局要设然后我们要设置元素在纵向上的布局方向,需要设置 align-items 属性,它有5个值可选:

  • stretch 填充整个容器(默认值)
  • flex-start 侧轴的起点对齐 (这里我们手动设置下子 view 的高度,来看的明显一些)
  • flex-end 侧轴的终点对齐
  • center 在侧轴中居中对齐
  • baseline 以子元素的第一行文字对齐

子 View 还有个属性 align-self,可以覆盖父元素的 align-items 属性,它有6个值可选:auto | flex-start | flex-end | center | baseline | stretch (auto 为继承父元素 align-items 属性,其他和 align-items 一致)
比如上面最后一个 baseline 的例子,我们把 item3 设置 align-self:flex-end;

此外还有 flex-wrap 属性,用于控制子 View 是否换行,有3个值可选:

  • nowrap:不换行(默认)
  • wrap:换行
  • wrap-reverse:换行,第一行在最下面

还有子 View 有个 order 属性,可以控制子元素的排列顺序,默认为0。
比如还是上面那个例子,我们把 item3 设置 order:-1; 可以把 item3 排在前面

swiper (轮播图)

滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为。
在这里插入图片描述
swiper (轮播图)典型用法示例
wxml中:

<swiper indicator-dots="true" autoplay="true" interval="5000" duration="1000" style='width: 100%'> 
<swiper-item wx:for="{{imgUrls}}" wx:for-item="imgItem"> 
<image src='{{imgItem}}' class="slide-image" width="355" height="150" /> 
</swiper-item> 
</swiper>

js中

data: {imgUrls: [ 
'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg', 
'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg', 
'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg' 
] }

swiper (轮播图)常用属性

  • indicator-dots Boolean 是否显示面板指示点
  • autoplay Boolean 是否自动切换
  • interval Number 自动切换时间间隔
  • duration Number 滑动动画时长

scroll-view

可滚动视图区域。使用竖向滚动时,需要给scroll-view一个固定高度
在这里插入图片描述
在这里插入图片描述

基础内容组件表单组件等

基础内容组件

  • icon 图标
  • text 文本
  • rich-text nodes属性可为Array和String类型,但推荐使用Array. nodes分为支持两种节点,分别为元素节点(type=node ,默认为元素节点)和文本节点(type=text)
  • progress 进度表

icon组件

在这里插入图片描述
图标库的类型有上面9种,如果要显示其它图标,可通过image标签自定义,可到下面网址下载
http://www.iconfont.cn/collections/index?spm=a313x.7781069.1998910419.4&type=1
在这里插入图片描述

text文本组件

  • text文本组件支持转义符 \ ,如换行\n,空格\t,<text/> 组件内只支持 <text/> 嵌套。除了文本节点以外的其他节点都无法长按选中
<view>
<text>你好世界 \t 你好世界</text>
<text>你好世界 \n 你好世界</text>
</view>

在这里插入图片描述
由图可得,text文本组件组件是放置在一行里,不同于view组件,每个view组件一行

rich-text富文本

  • 是小程序提供的富文本组件,能够在小程序中渲染出富文本字符串。比如可以在一个文本中包含不同的颜色、不同的字号、不用的背景颜色的文本(支持css样式)
  • nodes 属性推荐使用 Array 类型,由于组件会将 String 类型转换为 Array 类型,因而性能会有所下降
  • nodes现支持两种节点,通过type来区分,分别是元素节点和文本节点,默认是元素节点,在富文本区域里显示的HTML节点。

元素节点:type = node
progress(进度条)
progress组件:是小程序提供的进度条组件,能够实现小程序动态加载的。
在这里插入图片描述

导航

navigator 页面链接。
functional-page-navigator 仅在插件的自定义组件中有效,用于跳转到插件功能页。

媒体组件

  • audio 音频
  • image 图像
  • video 视频
  • camera 系统相机。该组件是原生组件,使用时请注意相关限制。
  • live-player 实时音视频播放。该组件是原生组件,使用时请注意相关限制。
  • live-pusher 实时音视频录制。该组件是原生组件,使用时请注意相关限制。

Image组件

在微信小程序中,要显示一张图片,有两种图片加载方式:
加载本地图片

<image class="widget__arrow" src="/image/arrowright.png" mode="aspectFill">
</image>

加载网络图片
直接给’src’这个属性附上地址,它会自动加载。

<image class="image_frame" src=" http://img1.3lian.com/2015/w7/85/d/101.jpg " mode="aspectFill">
</image>

Image组件

  • aspectFill 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。aspectFill同样保持图片的宽高比不会变形。但它让图片完全填满整个容器
  • aspectFit 用途:保证图片完整地装进容器,方式:选取宽高缩放值里较大的值来缩放,代价:容器无法装满,出现留白。
  • widthfix 宽度不变,高度自动变化,保持原图宽高比不变。
  • widthfix属性的最大特点是,图片将不会按照设定的尺寸呈现,比如设置image宽度为750px,高度为340px,如果设置mode=widthfix,则图片最终不会按照750px和340px呈现,除非原始图片切好是这个尺寸。这个属性让宽缩放至指定尺寸,再动态计算高度.

表单组件

button 按钮
checkbox 复选框
form 表单
input 输入框
label 标签
picker 滚动选择器
picker-view 嵌入页面的滚动选择器
radio 单选框
slider 滑动条
switch 开关
textarea 多行输入框

自定义组件

组件化编程

  • 组件就是一组功能和逻辑的封装, 以供重复使用
  • 开发者根据自身的需求也可以自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。

自定义组件基本创建步骤及解析

  • 类似于页面,一个自定义组件由 json wxml wxss js 4个文件组成。
  • 要编写一个自定义组件,新建一个components目录,在components目录右键再新建一个item目录,然后在item目录右键新建一个Component,命名为item,会自动生成item.json、item.wxml、item.js、item.wxss文件:

json配置:

在完成上面item组件的创建以后, 打开item.json

{
"component": true, // 表示item这4个文件是一个定义组件
"usingComponents": {} // 可选项, 此属性表示在这个组件中还可使用其它组件
}

js创建:

打开item.js, 这个文件定义item组件的属性列表, 数据及方法
// 定义的组件

Component({
//组件对外开发的属性
properties: {
content: {
type: String,
value: ''
},
iconTypes: {
type: Array,
vlaue: []
}
},

//组件的私有初始数据

data: {
	array:['success', 'info', 'warn', 'waiting', 'cancel', 'download', 'search', 'clear']
},
//组件的方法列表
methods: {
clickMe: function () { // 根据需求定义事件
	console.log("you have clicked me");
}
}
})

item.wxss 样式:

  • 自定义组件拥有自己的 wxml 模版 和 wxss 样式
  • 需要注意的是,wxss样式只能通过类选择器(.class)来指定
/* btn 是组件item.wxml 中的button标签的类样式 */
.btn {
    color: red 
}

item.wxml 模板:

  • item.wxml 的内容就是 组件模板
<view>
<!--使用组件中的content属性--> 
<!--给conent一个值hello, hello会传递到item.js中的content属性中, 然后使用{{}}把它取出来 -->
<view>{{content}} word</view>
<!--使用组件中的data-->
<block wx:for='{{array}}'>
<icon type='{{item}}'></icon>
</block>
<!--使用组件中的methods-->
<view>
	<button size='mini' bindtap='clickMe' class='btn'>click here</button>
</view>
</view>
<view>根据情况, 可任意增加或减少, 整个页面内容就是组件模板</view>

index页面创建(使用组件)

现在 index.wxml 页面要使用item模板组件, 则需要在index.json中做如下配置:

{
"usingComponents": {
"myitem": "/components/item/item"
}
}

这就表示要使用的组件是在/components/item/item, 组件名称(标签名)是myitem

<view>本页面为index.wxml, 如下的myItem为自定义组件</view>
<view>
<myitem content="你好"></myitem>
</view>
<view>本页面的其它内容</view>
myitem标签展示出来的内容就是上面item.wxml文件中的所有内容
而myitem仅仅是index.wxml中的一个标签

触发相应事件:

在index.wxml中的自定义组件绑定事件, 通过点击自定义组件myitem触发
如上所示, 模板组件会触发一个事件, 再触发成功回调函数 (如下this.triggerEvent)

<view>
<myitem content="你好" bindmyevent="confirm"></myitem> <!-- 给myitem绑定一个点击事件confirm -->
</view>
/*index.js*/
Page({
data: {},
confirm : function() {
console.log("触发成功");
}
})


/*item.js*/
Component(properties:{ }, 
data: {   }, 
methods: {    
clickMe: function () {     
console.log("you have clicked me");      // 触发成功回调      
this.triggerEvent('myevent');   // triggerEvent触发指定对象的指定事件, 我点击的是myitem标签, this也就表示它   
 }  
}
})

注意:

  • 在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。只能用class类选择器
  • 在自定义组件的 js 文件中,需要使用 Component() 来注册组件,并提供组件的属性定义、内部数据和自定义方法。
  • 组件的属性值和内部数据将被用于组件 wxml 的渲染,其中,属性值是可由组件外部传入的。而组件的data内部数据只能用于组件内部使用,不能从外部传入。

模版数据绑定

  • 与普通的 WXML 模版类似,可以使用数据绑定,这样就可以向子组件的属性传递动态数据。就像前面content=“你好” ,组件的属性 content将收到页面传递的数据。
  • 注意在wxml中因不区别大小写,如果属性名有多个单词组合,如js中的属性innerText要写成inner-text的形式。在js中变量名中不允许出现“-”。如果想要统一名称,可在js中和wxml中统一用inner_text这样的形式。具体如何表示只是个人习惯。

Page 和 Component

  • Component 是 Page 的超集
  • 事实上,小程序的页面也可以视为自定义组件。因而,页面也可以使用Component构造器构造,拥有与普通组件一样的定义段与实例方法。但此时要求对应 json 文件中包含usingComponents定义段。其实组件的渲染流程、方式,跟页面没多大区别

自定义组件模版和样式

组件模版

  • 组件模版的写法与页面模板相同。组件模版与组件数据结合后生成的节点树,将被插入到组件的引用位置上。
  • 在组件模板中可以提供一个 节点,用于承载组件引用时提供的子节点。
  • 只有一个slot节点时,组件开始标签和结束标签中间的内容,会插入到组件模块solt节点的位置。
    示例:
    在item.wxml中添加
<slot></slot>

在index.wxml中添加修改代码

<myitem content="你好">
	<view>这里是插入到组件slot中的内容</view> 
</myitem>

组件wxml有多个slot

默认情况下,一个组件的wxml中只能有一个slot。需要使用多slot时,可以在组件js中声明启用。

Component({ 
options: { 
multipleSlots: true // 在组件定义时的选项中启用多slot支持 
}, 
})

此时,可以在这个组件的wxml中使用多个slot,以不同的 name 来区分。

<view class="wrapper">
<slot name="before"></slot>
<view>这里是组件的内部细节</view>
<slot name="after"></slot>
</view>

使用时,用 slot 属性来将节点插入到不同的slot上。

<view>
<multisolt>
<!-- 这部分内容将被放置在组件 <slot name="before"> 的位置上 -->
<view slot="before">这里是插入到组件slot name="before"中的内容</view>
<!-- 这部分内容将被放置在组件 <slot name="after"> 的位置上 -->
<view slot="after">这里是插入到组件slot name="after"中的内容</view>
</multisolt>
</view>
</view>

组件样式

  • 组件对应 wxss 文件的样式,只对组件wxml内的节点生效。编写组件样式时,需要注意以下几点:
  • 组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用class选择器。
  • 组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
  • 子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
  • 继承样式,如 font 、 color ,会从组件外继承到组件内。
  • 除继承样式外, app.wxss 中的样式、组件所在页面的的样式对自定义组件无效。

#a { } /* 在组件中不能使用 /
[a] { } /
在组件中不能使用 /
button { } /
在组件中不能使用 /
.a > .b { } /
除非 .a 是 view 组件节点,否则不一定会生效 */

除此以外,组件可以指定它所在节点的默认样式,使用 :host 选择器(需要包含基础库 1.7.2 或更高版本的开发者工具支持)。

代码示例:

/* 组件 custom-component.wxss */ 
:host { color: yellow; } 
<!-- 页面的 WXML --> 
<custom-component>这段文本是黄色的</custom-component>

Component构造器、父子组件传值与组件事件

Component构造器

  • Component构造器可用于定义组件,调用Component构造器时可以指定组件的属性、数据、方法等。
    在这里插入图片描述
    属性
properties: {
    myProperty: { // 属性名
      type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
      value: '', // 属性初始值(可选),如果未指定则会根据类型选择一个
      observer: function(newVal, oldVal){} // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange'
    },
    myProperty2: String // 简化的定义方式
  }

生命周期函数

在这里插入图片描述

注意:在 properties 定义段中,属性名采用驼峰写法(propertyName);在 wxml 中,指定属性值时则对应使用连字符写法(component-tag-name property-name=“attr value”),应用于数据绑定时采用驼峰写法(attr="{{propertyName}}")。

使用 Component 构造器构造页面

  • 事实上,小程序的页面也可以视为自定义组件。因而,页面也可以使用 Component 构造器构造,拥有与普通组件一样的定义段与实例方法。但此时要求对应 json 文件中包含 usingComponents 定义段。
  • 此时,组件的属性可以用于接收页面的参数,如访问页面 /pages/index/index?paramA=123&paramB=xyz ,如果声明有属性 paramA 或 paramB ,则它们会被赋值为 123 或 xyz 。

组件间通讯与事件

组件间通信与事件

  • 组件间的基本通信方式有以下几种。
  • WXML 数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据。
  • 事件:用于子组件向父组件传递数据,可以传递任意数据。
  • 如果以上两种方式不足以满足需要,父组件还可以通过 this.selectComponent 方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法。

父组件向子组件传值

  • 方法1. page(父组件)在引用组件时能通过属性值设置,在子组件的properties 里面接收父组件传过来的数据
  • 方法2、 page在引用组件时通data-xxx设置,子组件中子组件名.js在this.dataset获取:

父组件向子组件传值—方法1

<call-phone phone="88888888"></call-phone>
Component({  
properties: {    
phone: String //简写    
/*     phone: {      type: String, //类型
 value: '', //初始值      
observer: function(newVal, oldVal) {}    }    */ 
 },  
attached: function() {    
console.log("this.properties.phone:" + this.properties.phone); //控制台打印:"88888888"  
},  
//...
})

注意:我们不要把data和properties里的变量设置成同一个名字,如果他们名字相同,properties里的会覆盖data里的。

父组件向子组件传值—方法2

<call-phone data-tel="88888888" ></call-phone>
Component({  
attached: function() {   
 console.log("this.dataset.tel:" + this.dataset.tel); //控制台打印:"88888888"    // 设置properties值用setData()   
 this.setData({      
phone: this.dataset.tel   
 });  
},  
//...
})
<call-phone data-tel="88888888" ></call-phone>
Component({  
attached: function() {   
 console.log("this.dataset.tel:" + this.dataset.tel); //控制台打印:"88888888"    // 设置properties值用setData()   
 this.setData({      
phone: this.dataset.tel   
 });  
},  
//...
})

子组件中的变量要传到page页面

组件中的变量要传到page页面,可以通过事件触发this.triggerEvent()来实行:

Component({  
methods: {    
callPhone() {      
var myEventDetail = {msg: '来自component的信息',  tel: '88888888' } 
// detail对象,提供给事件监听函数      
var myEventOption = {} // 触发事件的选项     
 this.triggerEvent('myevent', myEventDetail, myEventOption)   
 }
}
})
子组件中的变量要传到page页面
<!--index.wxml-->
<!--"bindmyevent"属性与上面"myevent"对应,当自定义组件触发"myevent"事件时,调用"call"方法 -->
<call-phone bindmyevent="call"></call-phone>
//index.js
Page({  
call: function(e) {    
console.log(e.detail.msg);//控制台打印:"来自component的信息"    wx.makePhoneCall({      phoneNumber: e.detail.tel    })
}
})

监听事件

  • 事件系统是组件间通信的主要方式之一。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。
  • 监听自定义组件事件的方法与监听基础组件事件的方法完全一致:
<component-tag-name bindmyevent="onMyEvent" />
Page({ 
onMyEvent: function(e)
{ 
	console.log(e.detail) // 自定义组件触发事件时提供的detail对象
 } 
})

触发事件

自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项:

<!-- 在自定义组件中 --> 
<button bindtap="onTap">
点击这个按钮将触发“myevent”事件</button>
 Component(
{methods: { 
onTap: function(){ 
var myEventDetail = {} // detail对象,提供给事件监听函数 
var myEventOption = {} // 触发事件的选项
 this.triggerEvent('myevent', myEventDetail, myEventOption) 
}
 } 
})
发布了182 篇原创文章 · 获赞 33 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42554191/article/details/104025415