文章目录
小程序组件·上
组件是视图层的基本组成单元,自带一些功能与微信风格的样式,绝大部分标签(包括开始标签和结束标签)都是组件。
组件分为8类:基础内容类、表单类、视图容器类、媒体类、画布类、导航类、地图类、开放能力类。
官网组件介绍的地址
以下示例中演示了官网中介绍的各种组件的属性设置的效果
1.视图容器类组件
视图容器主要是控制页面的内容,它相当于一个盒子,容器里的组件相当于更小的盒子。
(1)view
示例:
//view.wxml中
<view>
<view>view组件:</view>
<view class='view-parent-container' hover-class='hover-parent-container'>
<view class='view-container'
hover-class='hover-container'
hover-stop-propagation='true'
hover-start-time='500'
hover-stay-time='300'>
</view>
</view>
</view>
其中的hover-class就是鼠标点击事件触发的效果
//view.wxss中
.view-parent-container{
width:300rpx;
height: 300rpx;
background: yellowgreen;
}
.hover-parent-container{
background: #fff;
}
.view-container{
width: 200rpx;
height: 200rpx;
background: chocolate;
color: #fff;
text-align: center;
line-height: 200rpx;
}
.hover-container{
background:rgba(0,0,0,0.7);
}
效果:
(有hover-stop-propagation='true’属性的效果:)
这时会引用外层组件的hover-class效果,所以当点击巧克力色块时,外面的绿色框会显示白色背景,如果不设置该属性或设置为false时,为下方图片的效果。
(hover-stop-propagation=‘false’,即不写这条属性的效果:)
(2)scroll-view
滚动容器组件
//.wxml:
<!-- scroll-view -->
<view>scroll-view组件</view>
<view class='section'>
<view class="section_title">竖向滚动</view>
<scroll-view style='height:200px'
scroll-y
bindscrolltoupper="upper"
bindscrolltolower="lower"
bindscroll="scroll"
scroll-into-view="{{toView}}"
scroll-top="{{scrollTop}}"
enable-back-to-top="true"
scroll-with-animation="true">
<view id="green" class="scroll-view-item bc_green"></view>
<view id="red" class="scroll-view-item bc_red"></view>
<view id="yellow" class="scroll-view-item bc_yellow"></view>
<view id="blue" class="scroll-view-item bc_blue"></view>
</scroll-view>
<view class="btn-area">
<button size="mini" bindtap="tap">click me to scroll into view</button>
<button size="mini" bindtap="tapMove">click me to scroll</button>
</view>
</view>
<view class="section">
<view class="section_title">横向滚动</view>
<scroll-view class="scroll-view_H" scroll-x style="width:100%;"></scroll-view>
<view id="green" class="scroll-view-item_H"></view>
<view id="red" class="scroll-view-item_H"></view>
<view id="yellow" class="scroll-view-item_H"></view>
<view id="blue" class="scroll-view-item_H"></view>
</view>
//.wxss:
.section{
margin-left: 80rpx;
}
.section_title{
text-align: center
}
.scroll-view_H {
height: 200px;
margin: 0 auto;
white-space: nowrap;
}
.scroll-view-item_H{
display: inline-block;
width: 100%;
height: 200px;
}
.scroll-view-item{
width: 100%;
height: 200px;
}
.bc_green{
background:green;
}
.bc_red{
background: red;
}
.bc_yellow{
background-color: yellow;
}
.bc_blue{
background: blue;
}
var order=['green','red','yellow','blue']
Page({
/**
* 页面的初始数据
*/
data: {
toView:'green',
scrollTop:0//距离顶部多远时跳到顶部
},
upper:function(e){
console.log(e)
},
lower:function(e){
console.log(e)
},
scroll:function(e){
console.log(e)
},
tap:function(e){
for(var i=0;i<order.length;i++){
if(order[i]===this.data.toView){
this.setData({
toView:order[i+1]
})
break
}
}
},
tapMove:function(e){
this.setData({
scrollTop:this.data.scrollTop+20
})
}
})
设置了一个横向滚动条和一个纵向滚动条,在纵向滚动条上设置了各种属性属性的具体介绍可看官网scroll-view
最开始会显示scroll-into-view属性对应的色块
两个bindtap事件对应的效果分别是:
tap:点击一次按钮,滚动到下一个子元素
tapMove,每点击一次,色块向上移动20px
横向滚动条不设置宽度为100%时,默认就是100%
横向滚动条设置了display:inline-block,和white-space:nowrap,这里有很好的解释→知乎:css display: inline-block;实现横向滚动
(3)swiper
轮播组件
<!--swiper.wxml-->
<view class='page-body'>
<swiper
indicator-dots='{{indicatorDots}}'
autoplay='{{autoplay}}'
interval='{{interval}}'
duration='{{duration}}'>
<block wx:for="{{background}}" wx:key="*this">
<swiper-item >
<view class='swiper-item {{item}}'></view>
</swiper-item>
</block>
</swiper>
</view>
用一个for循环把所定义的子元素数组view定义出来;
background是一个js中定义的一个字符数组;
*this表示当前元素,与item类似,但是*this的使用只能是字符串或者元素数组
.js文件中的代码如下所示:
// swiper.js
Component({
/**
* 组件的初始数据
*/
data: {
background: ['demo-text-1', 'demo-text-2', 'demo-text-3'],
indicatorDots: true,
vertical: false,
autoplay: false,
interval: 2000,
duration: 300
},
})
注意:这里最外层用的是Component,在添加change事件时会报错:
Component “Pages/swiper/swiper” does not have a method “changeIndicatorDots” to handle event “change”.
.wxss中的代码如下所示:
/* swiper.wxss */
.page-body{
width: 100%;
}
.swiper-item{
display: block;
height: 150px;
}
.demo-text-1{
position: relative;
align-items: center;
/* 设置横向位置 */
justify-content: center;
background-color: #1AAD19;
color: #ffffff;
font-size: 36rpx;
}
.demo-text-1:before{
content: 'A';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.demo-text-2{
position: relative;
align-items: center;
justify-content: center;
background-color: #2782D7;
color: #ffffff;
font-size: 36rpx;
}
.demo-text-2:before{
content: 'B';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.demo-text-3{
position: relative;
align-items: center;
justify-content: center;
background-color: #F1F1F1;
color: #353535;
font-size: 36rpx;
}
.demo-text-3:before{
content: 'C';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
在编写代码时,由于漏掉了–>
.swiper-item{
display: block;
height: 150px;
}
界面中只能显示三个小圆点,加上之后才显示出如下界面:
(4)movable-view
可支持移动和缩放的组件
该组件必须放在一个可移动区域内(movable-area)
代码:
.wxml文件:
<view>
<view>可缩放movable-view</view>
<movable-area style="height:200px;width:200px;background:red;margin:0 auto;"
scale-area>
<movable-view style="height:50px;width:50px;background:blue;"
direction="all"
bindchange="onChange"
bindscale="onScale"
scale
scale-min="0.5"
scale-max="4"
scale-value="3">
</movable-view>
</movable-area>
</view>
.js文件:
Page({
data:{
x:0,
y:0
},
onChange:function(e){
console.log('this is touch change');
console.log(e.detail);
},
onScale:function(e){
console.log('this is scale change');
console.log(e.detail)
}
})
x,y代表movable-view的初始位置,初始在左上角;
onChange事件对应的是触摸事件;
onScale事件对应的是缩放事件;
加上scale-area属性后才能使用缩放功能。
效果:
红色区域是movable-area区域,蓝色区域是movable-view区域;
当movable-view的区域小于movable-area时,如图,movable-view只能在movable-view区域内移动;
当movable-view的区域大于movable-area时,movable-view也只能在覆盖movable-area的区域移动;
(5)cover-view和cover-image
和view组件不同的是,它可以盖在canvas、video、camera、map等原生组件上,实现一些自己的功能;
cover-view是覆盖在原生组件上的文本视图
cover-image是覆盖在原生组件上的图片视图,可嵌套在cover-view里
.wxml标签框架如下所示(放在video原生组件中):
<video id="myVideo" src='http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400'>
<cover-view>
<cover-view>
<cover-image src='./image/play.png'></cover-image>
</cover-view>
<cover-view>
<cover-image src='./image/pause.png'></cover-image>
</cover-view>
<cover-view>00:00</cover-view>
</cover-view>
</video>
2.基础内容组件
基础内容组件包括icon、text、rich-text、和progress
icon的样式如下所示:
代码如下:
<view>
<view>图标们</view>
<view>
1:<icon type="success" size="93" />成功
</view>
<view>
2:<icon type="info" size="93" />提示
</view>
<view>
3:<icon type="warn" size="93" />警告
</view>
<view>
4:<icon type="waiting" size="93" />等待
</view>
<view>
5:<icon type="success" size="23" />多选-已选择
</view>
<view>
6:<icon type="circle" size="23" />多选-未选择
</view>
<view>
7:<icon type="warn" size="23" />表单中出现错误
</view>
<view>
8:<icon type="success_no_circle" size="23" />单选-已选择
</view>
<view>
9:<icon type="download" size="23" />下载
</view>
<view>
10:<icon type="info_circle" size="23" />表单中的信息提示
</view>
<view>
11:<icon type="cancel" size="23" />信息中的关闭或停止
</view>
<view>
12:<icon type="search" size="23" />用于搜索控件中
</view>
</view>
text的各种属性对比:
代码:
<view>text基础内容组件:</view>
<view>
<text selectable="{{true}}" space="ensp" decode="{{true}}">1--ensp的(半个中文空格)\nMy name is component 英文后面有个 \;</text>
<text selectable="{{true}}" space="emsp">\n\n2--emsp的一个中文空格\nMy name is component</text>
<text selectable="{{true}}" space="emsp">\n\n3--前面是nbsp的一个英文空格\nMy name is component\n因为没写decode="{{true}}",所以能看到 </text>
</view>
效果:
nbsp的还是根据字体设置的空格大小
rich-text:
rich-text内不能再嵌套rich-text组件
rich-text的一个重要属性:nodes,nodes可以用String和Array,但因为String类型最后会转成Array类型,所以推荐使用Array类型
具体说明看文档rich-text基础内容组件
代码:
.wxml中:
<view>
<view>rich-text基础内容组件:</view>
<rich-text nodes="{{nodes}}"
bindtap="tap"
bindtouchstart="touchstart"
bindtouchmove="bindtouchmove"
bindtouchcancel="bindtouchcancel"
bindtouchend="bindtouchend"
bindlongpress="longtap">
</rich-text>
</view>
.js中:
Page({
/**
* 页面的初始数据
*/
data: {
nodes:[{
name:'div',
attrs:{
class:'div_class',
style:'line-height:60px;color:red;'
},
children:[{
type:'text',
text:'Hello World!'
}]
}]
},
tap:function(e){
console.log('tap')
},
touchstart(){
console.log('touchstart')
},
bindtouchmove(){
console.log('bindtouchmove')
},
bindtouchcancel(){
console.log('bindtouchcancel')
},
bindtouchend(){
console.log('bindtouchend')
},
longtap(){
console.log('longtap')
},
})
在写nodes节点中的attrs时,因为没认真读文档,本来attrs是Object类型,结果写的时候在右边的{}外面加了一层[](加了[]相当于类型变成了Array类型),没有显示出文字,正常情况下的文字是这样的:
按下再弹起时控制台的文字:
长按时控制台的文字:
可以发现一个很有意思的现象,按下和长按分别在touchend的前方和后方~~
手指移动时控制台的文字:
progress:
.wxml文件:
<progress show-info="{{true}}"
stroke-width="12"
percent='{{percentValue}}'
activeColor="#13c3a1"
backgroundColor="#fff"
active-mode="forwards">
这里可以写百分数哎O(∩_∩)O
</progress>
.js文件:
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let timer;
timer=()=>{
setTimeout(()=>{
const value=this.data.percentValue;
this.setData({
percentValue:value<100?value+10:value
});
timer()
},2000);
}
timer();
},
关于let变量可以参考:转载的关于let变量
以上四个基础内容组件笔记做完了,虽然看着很简单的内容,在自己写代码的时候愣是写错好几个地方,比如在写progress时,percent属性后面要写成’{{percentValue}}’,使它变成一个动态值,不然进度条就没有改变[哭泣.jpg]
3.表单组件
表单组件有:button、checkbox、form、input、label、picker、picker-view、radio、switch、text-area,文档中有详细介绍,只记一些自己感觉难的部分。
button:
open-type="getUserInfo"时,点击按钮,控制台会出现一些信息,其中的encryptedData表示加密的敏感信息,如果想要获取这些敏感信息,需要把encryptedData、AppId、以及SessionKey发送到第三方服务器,第三方服务器通过解密算法获取到敏感信息。
checkbox:
checkbox如果没有和group一起使用,即用的是<checkbox>
标签时当checkbox状态发生改变时,拿不到它的状态值;
如果用<checkbox-group>
标签包含了<checkbox>
,点击每个checkbox时,可以获取到checkbox的状态
form:
可以将用户输入的switch、input、checkbox、slider、radio、picker信息一块提交;
catchsubmit属性是阻止冒泡,即submit和reset事件不会冒泡到父节点
form表单可以方便地帮助我们进行表单的提交和信息的重置
input:
有输入时对手机键盘的各种操作
label:
label组件可以和控件关联在一起,当我们点击label组件时,相关联的表单组件也会产生一个点击的行为,目前可以绑定的组件有button、checkbox、radio、switch组件
picker:
选择器,比如填写收货地址时,支持5种选择器
picker选择器需要详细记录一下,尤其是它的级联方法,很神奇O(∩_∩)O
普通选择器:
wxml代码:
<view style="background:pink;">
<view>普通选择器</view>
<picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
<view>
当前选择:{{array[index]}}
</view>
</picker>
</view>
.js代码:
Page({
data:{
array:['美国','中国','巴西','日本'],
index:0
},
bindPickerChange:function(e){
console.log('picker发送选择改变,携带值为',e.detail.value)
this.setData({
index:e.detail.value
})
}
})
效果:
多列选择器:
wxml代码:
<view style="background:gray;">
<view>多列选择器</view>
<picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}">
<view>
当前选择:{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}}
</view>
</picker>
</view>
js代码:
Page({
data:{
multiArray:[['无脊椎动物','脊椎动物'],['扁形动物','线形动物','环节动物','软体动物','节肢动物'],['猪肉绦虫','吸血虫']],
multiIndex:[0,0,0]
},
bindMultiPickerChange:function(e){
console.log('bindMultiPickerChange')
this.setData({
multiIndex:e.detail.value
})
},
bindMultiPickerColumnChange:function(e){
console.log('修改的列为',e.detail.column,',值为',e.detail.value);
var data={
multiArray:this.data.multiArray,
multiIndex:this.data.multiIndex
};//将现在显示的字改掉
data.multiIndex[e.detail.column]=e.detail.value;
switch(e.detail.column){
case 0:
switch(data.multiIndex[0]){
case 0:
data.multiArray[1]=['扁形动物','线形动物','环节动物','软体动物','节肢动物'];
data.multiArray[2]=['猪肉绦虫','吸血虫'];
break;
case 1:
data.multiArray[1]=['鱼','两栖动物','爬行动物'];
data.multiArray[2]=['鲫鱼','带鱼'];
break;
}
data.multiIndex[1]=0;
data.multiIndex[2]=0;
break;
case 1:
switch(data.multiIndex[0]){
case 0:
switch(data.multiIndex[1]){
case 0:
data.multiArray[2]=['猪肉绦虫','吸血虫'];
break;
case 1:
data.multiArray[2]=['蛔虫'];
break;
case 2:
data.multiArray[2]=['蚂蚁','蚂蟥'];
break;
case 3:
data.multiArray[2]=['河蚌','蜗牛','蛞蝓'];
break;
case 4:
data.multiArray[2]=['昆虫','甲壳动物','蛛形动物','多足动物'];
break;
}
break;
case 1:
switch(data.multiIndex[1]){
case 0:
data.multiArray[2]=['鲫鱼','带鱼'];
break;
case 1:
data.multiArray[2]=['青蛙','娃娃鱼'];
break;
case 2:
data.multiArray[2]=['蜥蜴','龟','壁虎'];
break;
}
break;
}
data.multiIndex[2]=0;
console.log(data.multiIndex);
break;
}
this.setData(data);
}
})
效果:
这个就相当于一个级联选择器~~~
时间选择器:
wxml代码:
<view style="background:orange">
<view>时间选择器</view>
<picker mode="time" value="{{time}}" start="09:01" end="21:01" bindchange="bindTimeChange">
<view>
当前选择:{{time}}
</view>
</picker>
</view>
js代码:
Page({
data:{
time:'09:01'
},
bindTimeChange:function(e){
console.log('picker发送选择改变,携带值为',e.detail.value,',hahaha');
this.setData({
time:e.detail.value
})
}
})
效果:
省市区选择器:
wxml代码:
<view>
<view>省市区选择器</view>
<picker mode="region" bindchange="bindRegionChange">
<view>
当前选择:{{region[0]}},{{region[1]}},{{region[2]}}
</view>
</picker>
</view>
js代码:
Page({
data:{
},
bindRegionChange:function(e){
console.log('picker发送选择改变,携带值为',e.detail.value);
this.setData({
region:e.detail.value
})
}
})
效果:
picker-view:
wxml代码:
<view>
<view>{{year}}年{{month}}月{{day}}日</view>
<picker-view value="{{value}}" indicator-style="height:50px" style="width:100%;height:300px;" bindchange="bindChange">
<picker-view-column>
<view wx:for="{{years}}" wx:key="*this" style="line-height:50px">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{months}}" wx:key="*this" style="line-height:50px">{{item}}月</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{days}}" wx:key="*this" style="line-height:50px">{{item}}日</view>
</picker-view-column>
</picker-view>
</view>
js代码:
const date=new Date()
const years=[]
const months=[]
const days=[]
for(let i=1990;i<=date.getFullYear();i++){
years.push(i);
}
for(let i=1;i<=12;i++){
months.push(i);
}
for(let i=1;i<=31;i++){
days.push(i);
}
Page({
data:{
years:years,
year:date.getFullYear,
months:months,
month:2,
days:days,
day:2,
value:[0,1,1]
},
bindChange:function(e){
const val=e.detail.value
this.setData({
year:this.data.years[val[0]],
month:this.data.months[val[1]],
day:this.data.days[val[2]]
})
}
})
radio:
单选框组件,radio-group和checkbox-group一样,都可以在子元素发生变化时触发一个change事件
代码如下:
wxml中的代码:
<view>
<view>带group的样式</view>
<view>
<radio-group bindchange="radioChange">
<label wx:for="{{items}}" wx:key="{{item.value}}">
<view>
<radio value="{{item.value}}" checked="{{true}}" />
</view>
<view>{{item.name}}</view>
</label>
</radio-group>
</view>
</view>
js中的代码:
Page({
data:{
items:[
{value:'USA',name:'美国'},
{value:'CHN',name:'中国',checked:'true'},
{value:'BRA',name:'巴西'},
{value:'JPN',name:'日本'},
{value:'ENG',name:'英国'},
{value:'FRA',name:'法国'},
]
},
radioChange:function(e){
console.log('radio发生change事件,携带value值为:',e.detail.value)
var items=this.data.items;
for(var i=0,len=items.length;i<len;++i){
items[i].checked=items[i].value==e.detail.value
}
this.setData({
items:items
})
}
})
text-area组件:
和单行输入框的组件基本一样,区别在于有个auto-height属性
小程序组件·上 完结 撒花~~~O(∩_∩)O