文章目录
前言
前面我们学习了微信小程序的环境介绍和一些基本的使用,而今天这篇文章我将为大家介绍微信小程序开发的详细使用,今天介绍的是微信小程序开发的模板与配置。
1. WXML 模板语法
1.1 数据绑定
数据绑定用于将逻辑层的数据呈现到界面上,在微信小程序中,页面分别由四个文件组成,其中之一就是逻辑处理文件(.js文件),负责页面逻辑内容的处理。数据绑定将逻辑层的数据与视觉层进行通信,实现数据的动态更新和双向传递。
数据绑定是单向的,从逻辑层到视觉层。在微信小程序中,数据必须要放在一个固定的地方,即该页面的逻辑层的data属性中。页面的逻辑层就是该页面的 .js 文件中的data对象,该对象中的所有属性都可以在界面中访问到。
在微信小程序中实现数据绑定,首先需要在 .js 文件的 data 中定义数据,然后在 WXML 中通过 Mustache 语法获取到 .js 中的数据。
在 .js 文件的 data 中定义数据:
Page({
/**
* 页面的初始数据
*/
data: {
info: "数据绑定"
}
|
在 .WXML 文件中使用 Mustache语法: {{变量名}} 来获取到指定数据:
<text>{{info}}</text>
Mustache 语法主要运用于下面的场景:
- 绑定内容
- 绑定属性
- 运算(三元运算、算术运算等)
(❁´◡`❁)动态绑定数据
为什么需要数据绑定呢?因为有些时候的数据是动态的,不是规定死的,通过 Mustache 的数据绑定可以获取到动态变化的数据。
Page({
/**
* 页面的初始数据
*/
data: {
// 根据需要更改需要的图片的位置
imagePath: "/images/1.jpg"
},
},
<image src="{{imagePath}}" mode="widthFix"/>
(❁´◡`❁)三目运算
Page({
/**
* 页面的初始数据
*/
data: {
randomNum: Math.random() * 10 //生成10以内的随机数
},
},
<text>{{randNum > 5 ? '大于5的数字' : '小于5的数字'}}</text>
(❁´◡`❁)算术运算
Page({
/**
* 页面的初始数据
*/
data: {
info: Math.random().toFixed(2) //生成0-1之间的两位小数
},
},
<text>'生成的0-100之间的随机整数'{{info * 100}}</text>
1.2 事件绑定
什么是事件?
事件是视图层到逻辑层的通讯方式。它可以将用户的行为反馈到逻辑层进行处理,同时绑定在组件上。当达到触发事件的条件时,就会执行逻辑层中对应的事件处理函数。事件可以携带额外信息,如id、dataset、touches等。事件还是连同WXML组件和JavaScript的桥梁。通过事件,开发者可以处理用户操作、小程序状态等场景。
小程序中常见的事件类型有三种:
类型 | 绑定方式 | 事件描述 |
---|---|---|
tap | bindtap 或 bind:tap | 手指触摸后马上离开,类似于 HTML 中的 click 事件 |
input | bindinput 或 bind:input | 文本框的输入事件 |
change | bindchange 或 bind:change | 状态改变时触发 |
事件对象的属性列表:
属性 | 类型 | 说明 |
---|---|---|
type | String | 事件类型 |
timeStamp | Integer | 页面打开到触发事件所经过的毫秒数 |
target | Object | 触发事件的组件的一些属性值集合 |
currentTarget | Object | 当前组件的一些属性值集合 |
detail | Object | 额外的信息 |
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
上面属性中:target 和 detail 是使用很多的两个属性。
target 和 currentTarget 的区别:
- target:这个属性指的是触发事件的元素,也就是用户与界面上的某个元素发生的交互行为所对应的元素。例如,如果用户点击了一个按钮,那么这个按钮就是target。
- currentTarget:这个属性指的是当前正在触发事件的元素,也就是事件绑定所在的元素。例如,如果在一个按钮的点击事件中,点击了按钮的父元素,那么 currentTarget 就是按钮的父元素。
target 是触发该事件的源头组件,而 currentTarget 则是当前事件所绑定的组件。
target和currentTarget的区别在于,target是指向触发事件的元素,而currentTarget是指向当前正在触发事件的元素。
<view class="outer-view" bind:tap="outerHandler">
<button type="primary">按钮</button>
</view>
点击内部的按钮时,点击事件以冒泡的方式向外扩散,也会触发外层 view 的 tap 事件处理函数。
此时,对于外层的 view 来说:
- e.target 指向的是触发事件的源头组件,因此,e.target 是内部的按钮组件
- e.currentTarget 指向的是当前正在触发事件的那个组件,因此,e.currentTarget 是当前的 view 组件
1.2.1 bindtap 事件
在小程序中,不存在 HTML 中的 onclick 鼠标点击事件,而是通过 tap 事件来响应用户的触摸行为,通过 bind:tap 或者 bindtap,可以为组件绑定 tap 触摸事件,语法如下:
<button type="primary" bind:tap="btnTapHandler">按钮</button>
在页面的 .js 文件中定义对应的事件处理函数,事件参数通过形参 event(一般简写成 e) 来接收:
和 .js 文件中 data 平级定义事件:
btnTapHandler(e) {
console.log(e)
},
当我们点击按钮的时候就会触发 btdTapHandler 事件:
上面示例中的事件处理的是简单的事件,在事件处理函数中还可以为 data 中的数据赋值,在事件函数中国需要调用 this.setData(Object) 方法 来给页面的 data 数据赋值。
首先我们在 data 中定义数据 count,初始值为 0:
count: 0
然后在 bindtap 事件处理函数中,为 data 数据赋值:
// 当发生该事件的时候会将count+1
btnTapHandler(e) {
this.setData({
count: this.data.count + 1
})
},
当然这些值都是比较死的,我们也可以将渲染层传来的参数赋值给 data 中的数据中,而要想拿到渲染层传来的参数,需要通过 event.target.dataSet.参数名 来获取到渲染层传来的指定参数的值,并且在渲染层传递参数也有点区别,不能直接 函数名(参数) 来调用函数,如果这样来调用函数的话,函数名(参数名) 则会被认为是函数名,在微信小程序的渲染层传递参数需要通过 data-参数名=“” 来进行传参。
btnTapHandler(e) {
this.setData({
count: e.target.dataset.count
})
},
渲染层传参:
<button bind:tap="btnTapHandler" type="primary" data-count="3">按钮</button>
但是这里有个问题,就是我们查看 data 中的 count 的类型的时候,可以发现这个 count 是 string 类型的,为什么呢?
因为我们 data-count=“3” “3” 是一个字符串,所以渲染层接收到的参数的类型就是 string 类的,那么如何传参才能使得渲染曾传递的参数的类型是 Integer 类型的呢?
需要借助 Mustache 语法来传递 Integer 类型的参数:
<button bind:tap="btnTapHandler" type="primary" data-count="{{3}}">按钮</button>
1.2.2 bindinput 事件
<input type="text" bindinput="inputHandler"/>
input {
/* 设置输入框的边框宽度为1像素,样式为实线,颜色为浅灰色(#eee) */
border: 1px solid #eee;
/* 设置输入框的外边距(周围的空间)为5像素。这使得输入框与其周围的元素之间有5像素的间距 */
margin: 5px;
/* 设置输入框的内边距(框与内容之间的空间)为5像素。这确保了输入框的内容与其边框之间有5像素的距离 */
padding: 5px;
/* 设置边框的圆角为3像素。这使得输入框的四个角看起来是圆形的,而不是完全的直角 */
border-radius: 3px;
}
inputHandler(e) {
console.log(e.detail.value)
},
每当输入框中的数据有更新,event.detail.value 中的值就会更新。
根据上面的事件传参,通过 input 事件也可以根据输入框中的值为 data 中的数据赋值:
先在 data 中定义 message 数据,并进行初始化。
message: '你好'
渲染层使用 Mustache 语法获取到 data 中的数据:
<input type="text" value="{{message}}" bindinput="inputHandler"/>
在 js 中将输入框中的数据赋值给 data 中的数据:
inputHandler(e) {
this.setData({
message: e.detail.value
})
},
启动之后,输入框会获取到 message 中的值:
然后我们修改输入框的值看能否赋值给 data 中的 message 数据。
change 事件后面再为大家介绍。
1.3 条件渲染
在微信小程序中可以使用 wx:if / wx:elif / wx:else 来实现条件渲染。
<view wx:if="{{condition}}">True</view>
condition: true
condition: false
如果要一次性控制多个组件的展示与隐藏,可以使用一个 <block></block> 标签将多个组件包装起来,并在<block> 标签上使用 wx:if 控制属性:
<block wx:if="{{condition}}">
<view>view1</view>
<view>view2</view>
</block>
注意: 并不是一个组件,它只是一个包裹性质的容器,不会在页面中做任何渲染。
在小程序中,直接使用 hidden=“{{ condition }}” 也能控制元素的显示与隐藏:
<view hidden="{{condition}}">条件为true隐藏,条件为false显示</view>
wx:if 与 hidden 的对比:
- 运行方式不同
- wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏
- hidden 以切换样式的方式(display: none/block;),控制元素的显示与隐藏
- 使用建议
- 频繁切换时,建议使用 hidden
- 控制条件复杂时,建议使用 wx:if 搭配 wx:elif、wx:else 进行展示与隐藏的切换
1.4 列表渲染
在微信小程序中可以使用 wx;for 根据指定的数组,循环渲染重复的组件结构:
首先在 data 中定义一个数组:
array: [
'小美',
'小帅',
'壮壮'
]
默认情况下,当前循环项的索引用 index 表示;当前循环项用 item 表示。
<view wx:for="{{array}}">
索引是:{{index}},当前项是:{{item}}
</view>
index 和 item 是默认的索引和循环项,我们也可以自定义索引和循环项:
- 使用 wx:for-index 可以指定当前循环项的索引的变量名
- 使用 wx:for-item 可以指定当前项的变量名
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
索引是:{{idx}},当前项是:{{itemName}}
</view>
类似于 Vue 列表渲染中的 :key,小程序在实现列表渲染时,也建议为渲染出来的列表项指定唯一的 key 值,从而提高渲染的效率:
array: [
{id: 1, name: '小美'},
{id: 2, name: '小帅'},
{id: 3, name: '壮壮'}
]
<view wx:for="{{array}}" wx:key="id">
索引是:{{index}},当前项是:{{item.name}}
</view>
对于我们上面的示例,没有适合的可以指定的 key 值,所以可以将索引 index 作为 key 值。
2. WXSS 模板样式
什么是 WXSS?
WXSS(WeiXin Style Sheets)是一套样式语言,用于描述WXML的组件样式。WXSS用于决定WXML的组件应该怎么显示,类似于网页开发中的CSS。为了适应广大的前端开发者,WXSS具有CSS大部分特性。同时,为了更适合开发微信小程序,WXSS对CSS进行了扩充以及修改。与CSS相比,WXSS扩展的特性有尺寸单位和样式导入等。
与 CSS 相比,WXSS 扩展的特性有:
- rpx 尺寸单位
- @import 样式导入
2.1 什么是 rpx 尺寸单位
rpx是微信小程序独有的、解决屏幕自适应的尺寸单位,可以根据屏幕宽度进行自适应,不论屏幕大小,规定屏幕宽为750rpx。通过rpx设置元素和字体的大小,小程序在不同尺寸的屏幕上,可以实现自动适配。
rpx与px之间的换算以iPhone6为例,iPhone6的屏幕宽度为375px,共有750个物理像素,则750rpx=375px=750物理像素,也就是1rpx=0.5px=1物理像素,因为设计师的图一般是二倍图,所以在iPhone6下直接使用测量出来的值来设置rpx就可以了。
正是因为这,官方建议:开发微信小程序时,设计师可以用 iPhone6 作为视觉稿的标准。
2.2 什么是样式导入
在微信小程序开发中,样式导入是一种使用WXSS提供的@import语法来导入外部样式表的方法。通过样式导入,可以将样式代码分离到单独的样式表中,以便更好地组织和管理代码。
使用@import语法,可以在WXSS文件中导入其他WXSS文件的样式。例如,可以在app.wxss文件中导入common.wxss文件中的样式,以便在整个小程序中共享和重用这些样式。
在样式导入时,需要指定需要导入的样式表的相对路径。例如,如果common.wxss文件位于与app.wxss文件同一目录下,可以使用@import "common.wxss"来导入该文件中的样式。
通过样式导入,可以提高代码的可维护性和可重用性,同时也有助于减少代码冗余和降低样式冲突的可能性。
2.3 全局样式和局部样式
全局样式:微信小程序中的全局样式是指在app.wxss文件中定义的样式。这些样式对小程序中的每个页面都有效,可以用来设置全局的样式风格,例如字体、颜色、布局等。通过在app.wxss文件中定义样式,可以让整个小程序的样式风格保持一致,提高了用户体验。
局部样式:微信小程序中的局部样式是指在页面级别的WXSS文件中定义的样式。这些样式只作用于对应的页面,不会影响其他页面。通过在页面级别的WXSS文件中定义样式,可以实现页面的个性化定制,使每个页面的样式都符合特定的需求和设计风格。
- 当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式
- 当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式
我们将鼠标放在对应的 CSS 样式中就会显示出权重。
2.3.1 全局配置
全局配置文件的常用配置项:
- pages:记录当前小程序所有页面的存放路径
- window:全局设置小程序窗口的外观
- tabBar:设置小程序底部的 tabBar 效果
- style:是否启用新版的组件样式(v2表示启用)
小程序窗口组成部分:
2.3.1.1 window 节点常用的配置项:
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
navigationBarTitleText | String | 字符串 | 导航栏标题文字内容 |
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如 #000000 |
navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持 black / white |
backgroundColor | HexColor | #ffffff | 窗口的背景色 |
backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light |
enablePullDownRefresh | Boolean | false | 是否全局开启下拉刷新 |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为px |
"window": {
"navigationBarTitleText": "WeChat",
"navigationBarBackgroundColor": "#FFFFFF",
"navigationBarTextStyle": "black",
"backgroundColor": "#efefef",
"backgroundTextStyle":"dark",
"enablePullDownRefresh":true,
"onReachBottomDistance": 100
}
注意:上拉触底默认距离为50px,如果没有特殊需求,建议使用默认值即可。
2.3.1.2 tabBar
微信小程序中的tabBar是指位于小程序底部或者顶部的一组固定导航按钮,通常包含 2-5个按钮,用于快速切换小程序的不同页面。这些按钮是固定的,不会随着页面滚动而消失。通过点击不同的tabBar按钮,用户可以快速切换到对应的功能页面。
在微信小程序中,tabBar是全局配置,即每个页面都会显示这个tabBar。开发者可以在微信小程序的app.json文件中配置tabBar,包括设置tabBar的标题、图标、背景色等样式,以及指定每个tab页面的路径。
通过合理地使用tabBar,可以为用户提供更好的导航和切换体验,提升小程序的用户满意度。在设计tabBar时,需要注意颜色、大小、字体等因素的统一,以保持小程序的整体风格的一致性。同时,需要考虑用户的使用习惯和逻辑,使tabBar符合用户的心理预期和使用习惯。
注意:
- tabBar中只能配置最少 2 个、最多 5 个 tab 页签
- 当渲染顶部 tabBar 时,不显示 icon,只显示文本
tabBar 的组成部分:
tabBar 节点的配置项:
属性 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
position | String | 否 | bottom | tabBar 的位置,仅支持 bottom/top |
borderStyle | String | 否 | black | tabBar 上边框的颜色,仅支持 black/white |
color | HexColor | 否 | tab 上文字的默认(未选中)颜色 | |
selectedColor | HexColor | 否 | tab 上的文字选中时的颜色 | |
backgroundColor | HexColor | 否 | tabBar 的背景色 | |
list | Array | 是 | tab 页签的列表,最少 2 个、最多 5 个 tab |
每个 tab 项的配置选项:
属性 | 类型 | 是否必填 | 描述 |
---|---|---|---|
pagePath | String | 是 | 页面路径,页面必须在 pages 中预先定义 |
text | String | 是 | tab 上显示的文字 |
iconPath | String | 否 | 未选中时的图标路径;当 postion 为 top 时,不显示 icon |
selectedIconPath | String | 否 | 选中时的图标路径;当 postion 为 top 时,不显示 icon |
注意:如果存在 tabBar,那么在 app.json 的 pages 选项中,需要将 tab 页面放在前面,否则这些 tabBar 是无法渲染出来的。
3. 网络数据请求
既然是小程序,肯定不可避免的需要向其他网站发送网络请求。但是处于安全考虑,小程序官方对数据接口的请求做出了限制:
- 只能请求 HTTPS 类型的接口
- 必须将接口的域名添加到信任列表中
配置域名在微信小程序管理后台中配置:
微信小程序向网站发送请求,需要调用微信小程序提供的 wx.request() 方法,通过这个方法可以发送 GET 或者 POST等其他请求类型的请求。
GET 请求:
wx.request({
url: 'https://www.baidu.com',
method: "GET",
success: (res) => {
console.log(res)
}
})
POST 请求:
wx.request({
url: 'https://www.baidu.com',
method: "POST",
data: {
name: 'zhangsan',
password: '123456'
},
success: (res) => {
console.log(res)
}
})
在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据。此时需要在页面的 onLoad 事件中调用获取数据的函数:
如果后端程序员仅仅提供了 http 协议的接口、暂时没有提供 https 协议的接口,此时为了不耽误开发的进度,我们可以在微信开发者工具中,临时开启「开发环境不校验请求域名、TLS 版本及 HTTPS 证书」选项,跳过 request 合法域名的校验
注意:跳过 request 合法域名校验的选项,仅限在开发与调试阶段使用.
跨域问题只存在于基于浏览器的 Web 开发中。由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题。
Ajax 技术的核心是依赖于浏览器中的 XMLHttpRequest 这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫做“发起 Ajax 请求”,而是叫做“发起网络数据请求”。