一、小程序项目组成部分
1.1、小程序项目基础组成部分
1.2、小程序代码构成
小程序官方建议把所有小程序的页面,都存放在 pages 目录中,以单独的文件夹存在。
1.3、app.json配置文件
1.4、project.config.json配置文件
1.5、sitemap.json配置文件
微信现已开放小程序内搜索,效果类似于PC网页的 SEO。sitemap.json 文件用来配置小程序页面是否允许微信索引。
当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索关键字和页面的索引匹配成功的时候,小程序的页面将可能展示在搜索结果中。
如果页面不允许被微信索引,将action配置成disallow。
二、组件
小程序中的组件也是由宿主环境提供的,开发者可以基于组件快速搭建出漂亮的页面结构。官方把小程序的组件分为了9大类,分别是:
1、视图容器
2、基础内容
3、因表单组件
4、导航组件
5、媒体组件
6、map 地图组件
7、canvas 画布组件
8、开放能力
9、无障碍访问
2.1、view组件
view普通视图区域,类似于 HTML 中的 div,是一个块级元素,常用来实现页面的布局效果。
<view class = "container1">
<view>A</view>
<view>B</view>
<view>C</view>
</view>
.container1 view{
height: 100px;
width:100px;
text-align: center;
line-height: 100px;
}
.container1 view:nth-child(1){
background-color: pink;
}
.container1 view:nth-child(2){
background-color:aqua;
}
.container1 view:nth-child(3){
background-color:lightcoral;
}
.container1{
display: flex;
justify-content: space-around;
}
2.2、view组件实现纵向滚动效果
<scroll-view class = "container1" scroll-y>
<view>A</view>
<view>B</view>
<view>C</view>
</scroll-view>
.container1 view{
height: 100px;
width:100px;
text-align: center;
line-height: 100px;
}
.container1 view:nth-child(1){
background-color: pink;
}
.container1 view:nth-child(2){
background-color:aqua;
}
.container1 view:nth-child(3){
background-color:lightcoral;
}
.container1{
height: 120px;
width: 100px;
border:1px solid red;
}
2.3、swiper组件
swiper组件实现轮播图
<swiper class="swiper-container" indicator-dots>
<!--第一张轮播图-->
<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>
.swiper-container{
height: 150px;
}
.item{
height: 100%;
text-align: center;
line-height: 150px;
}
swiper-item:nth-child(1) .item{
background-color: lightcoral;
}
swiper-item:nth-child(2) .item{
background-color: lightcyan;
}
swiper-item:nth-child(3) .item{
background-color: lightpink;
}
2.4、swiper组件常用属性
2.5、text组件
文本组件,类似于 HTML 中的 span 标签,是一个行内元素。
通过 text 组件的 selectable 属性,实现长按选中文本内容的效果:
<view>
<!--手机号支持长按选中操作-->
<text selectable>1800000000000</text>
</view>
通过 rich-text 组件的 nodes 属性节点,把 HTML 字符串渲染为对应的 UI 结构。
<rich-text nodes="<h1 style='color:red;'>标题<h1>"></rich-text>
2.6、button组件
按钮组件
功能比 HTML 中的 button 按钮丰富
通过 open-type 属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)
<view>--------------通过type指定按钮类型--------------</view>
<button>默认按钮</button>
<button type = "primary">主色调按钮</button>
<button type = "warn">警告按钮</button>
<view>--------------通过size = "mini"小尺寸按钮--------------</view>
<button size = "mini">默认按钮</button>
<button type = "primary" size = "mini">主色调按钮</button>
<button type = "warn" size = "mini">警告按钮</button>
<view>--------------通过plain镂空按钮--------------</view>
<button size = "mini" plain>默认按钮</button>
<button type = "primary" size = "mini" plain>主色调按钮</button>
<button type = "warn" size = "mini" plain>警告按钮</button>
2.7、image组件
<!--空图片-->
<image></image>
<!--使用src指定图片路径-->
<image src = "/images/example.jpg"></image>
image {
/*通过边框线证明image有默认的高和宽*/
border: 1px solid red;
}
image 组件的 mode 属性。
image 组件的 mode 属性用来指定图片的裁剪和缩放模式,常用的 mode 属性值如下:
三、模版与配置
3.1、数据绑定
在data中定义数据,在wxml中使用Mustache 语法绑定数据。
3.1.1、绑定内容
在页面对应的 .js 文件中,把数据定义到 data 对象中即可。如下
/**
* 页面的初始数据
*/
data: {
//字符串类型数据
info:"init data",
//数组类型数据
msg:[{msg:'HELLO'},{msg:'WORLD'}]
},
把data中的数据绑定到页面中渲染,使用 Mustache 语法(双大括号)将变量包起来即可。语法格式如下:
<view>{{info}}</view>
3.1.2、绑定属性
/**
* 页面的初始数据
*/
data: {
//字符串类型数据
info:"init data",
//数组类型数据
msg:[{msg:'HELLO'},{msg:'WORLD'}],
//动态绑定属性
imgSrc:"/images/example.jpg",
},
<!--Mustache 语法绑定属性-->
<image src="{{imgSrc}}" mode="widthFix"/>
3.1.3、运算(三元运算、算术运算等)
data: {
//字符串类型数据
info:"init data",
//数组类型数据
msg:[{msg:'HELLO'},{msg:'WORLD'}],
//动态绑定属性
imgSrc:"/images/example.jpg",
//三元运算,生成10以后的随机数
randomNum:Math.random()*10,
},
<view>{{randomNum>=5?'随机数大于等于5':'随机数小于5'}}</view>
3.2、事件绑定
3.2.1、小程序中的常用事件
事件对象的属性列表,当事件回调触发的时候,会收到一个事件对象event,它的详细属性如下表所示:
3.2.2、target 和currentTarget 的区别
target 是触发该事件的源头组件,而 currentTarget 则是当前事件所绑定的组件。举例如下:
点击内部的按钮时,点击事件以冒泡的方式向外扩散,也会触发外层view 的tap 事件处理函数。此时,对于外层的 view 来说:
e.target 指向的是触发事件的源头组件,因此,e.target 是内部的按钮组件。
e.currentTarget 指向的是当前正在触发事件的那个组件,因此,e.currentTarget 是当前的 view 组件。
3.2.3、bindtap 的语法格式
在小程序中,不存在 HTML 中的 onclick 鼠标点击事件,而是通过 tap 事件来响应用户的触摸行为。通过 bindtap,可以为组件绑定 tap 触摸事件,语法如下:
<button type="primary" bind:tap="btnTapHandler">触摸事件按钮</button>
在页面的 .js 文件中定义对应的事件处理函数,事件参数通过形参 event(一般简写成e)来接收:
/**
*事件绑定
*/
btnTapHandler(e){ // 按钮的 tap 事件处理函数
console.log(e)//事件参数对象 e
},
3.2.4、在事件处理函数中为 data 中的数据赋值
通过调用 this.setData(data0bject)方法,可以给页面 data 中的数据重新赋值,示例如下:
Page({
/**
*事件绑定 更改data中count的值
*/
changeCountHandler(){
this.setData({
count:this.data.count+1
})
},
/**
* 页面的初始数据
*/
data: {
//定义初始数据
count:0,
},
<button type="primary" bind:tap="changeCountHandler">触摸事件+1按钮</button>
<view>count当前值为:{{count}}</view>
3.2.5、事件传参
小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传递参数。例如,下面的代码将不能正常工作:
<button type="primary" bind:tap="changeCountHandler(123)">触摸事件+1按钮</button>
因为小程序会把 bindtap 的属性值,统一当作事件名称来处理,相当于要调用一个名称为 changeCountHandler(123)的事件处理函数。
可以为组件提供 data-自定义属性传参,其中代表的是参数的名字,示例代码如下:
<button type="primary" bind:tap="changeCountHandler" data-info="{{2}}">触摸事件按钮</button>
<view>count当前值为:{{count}}</view>
最终:
info 会被解析为参数的名字。
数值 2 会被解析为参数的值。
在事件处理函数中,通过 event.target.dataset.参数名 即可获取到具体参数的值,示例代码如下:
/**
*事件绑定 更改data中count的值
*/
changeCountHandler(e){
// dataset 是一个对象,包含了所有通过 data-* 传递过来的参数项
console.log(e.target.dataset)
// 通过 dataset 可以访问到具体参数的值
console.log(e.target.dataset.info)
this.setData({
count:this.data.count+e.target.dataset.info
})
},
/**
* 页面的初始数据
*/
data: {
//定义初始数据
count:0,
},
6.2.6、bindinput 的语法格式
在小程序中,通过 input 事件来响应文本框的输入事件,语法格式如下:通过 bindinput,可以为文本框绑定输入事件:
<input type="text" bindinput="inputHandler"/>
<view>当前输入值为:{{inputValue}}</view>
input{
border:1px solid #eee;
margin: 5px;
padding:5px;
border-radius: 5px;
}
Page({
/**
*事件绑定 更改data中count的值
*/
inputHandler(e){
// e.detail.value 是变化过后,文本框最新的值
console.log(e.detail.value)
this.setData({
inputValue:e.detail.value
})
},
/**
* 页面的初始数据
*/
data: {
//定义初始数据
inputValue:'',
},
四、条件渲染
4.1、wx:if
在小程序中,使用 wx:if="{{condition}}"来判断是否需要渲染该代码块,也可以用 wx:elif 和 wx:else 来添加 else 判断。如下:
/**
* 页面的初始数据
*/
data: {
//定义初始数据
type:0,
},
<!--如果type值等于1,页面显示数据为男-->
<view wx:if="{{type===1}}">男</view>
<!--如果type值等于2,页面显示数据为女-->
<view wx:elif="{{type===2}}">女</view>
<!--否则页面显示数据为保密-->
<view wx:else>保密</view>
4.2、结合<block>标签使用 wx:if
如果要一次性控制多个组件的展示与隐藏,可以使用一个<block></block>标签将多个组件包装起来,并在<block>标签上使用 wx:if 控制属性,示例如下:
<!--如果type值等于1,页面显示数据为A-->
<block wx:if="{{type===1}}">
<view>A</view>
<view>A</view>
<view>A</view>
</block>
<!--如果type值等于2,页面显示数据为B-->
<block wx:elif="{{type===2}}">
<view>B</view>
<view>B</view>
<view>B</view>
</block>
<!--否则页面显示数据为C-->
<block wx:else>
<view>C</view>
<view>C</view>
<view>C</view>
</block>
4.3、hidden
在小程序中,直接使用 hidden="{{condition}}" 也能控制元素的显示与隐藏。如下:
<view hidden="{{type===1}}">如果type等于1隐藏,否则显示。</view>
4.4、wx:if与 hidden的对比
运行方式不同
wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏。
hidden 以切换样式的方式(display: none/block;),控制元素的显示与隐藏。
使用建议
频繁切换时,建议使用 hidden。
控制条件复杂时,建议使用 wx:if 搭配 wx:elif、wx:else 进行展示与隐藏的切换。
五、列表渲染
5.1、wx:for
通过 wx:for 可以根据指定的数组,循环渲染重复的组件结构,语法示例如下:
/**
* 页面的初始数据
*/
data: {
//定义初始数组数据
array:['REACT','VUE','ANGULAR']
},
<view wx:for="{{array}}">
索引是:{{index}},当前项是:{{item}}
</view>
默认情况下,当前循环项的索引用 index 表示;当前循环项用 item 表示。
5.2、手动指定索引和当前项的变量名*
使用 wx:for-index 可以指定当前循环项的索引的变量名使用 wx:for-item 可以指定当前项的变量名。如下:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
索引是:{{idx}},当前项是:{{itemName}}
</view>
5.3、wx:key 的使用
类似于 Vue 列表渲染中的 :key,小程序在实现列表渲染时,也建议为渲染出来的列表项指定唯一的 key 值从而提高渲染的效率,示例代码如下:
/**
* 页面的初始数据
*/
data: {
//定义初始数组数据
listValue:[
{id:1,name:'REACT'},
{id:2,name:"VUE"},
{id:3,name:"ANGULAR"}
]
},
<view wx:for="{{listValue}}" wx:key="id">
{{item.name}}
</view>