WXML 模板语法 - 数据绑定
在data中定义页面的数据
在页面对应的 .js 文件中,把数据定义到 data 对象中即可:
Page({
data: {
// 字符串类型的数据
info: 'init data',
// 数据类型的数据
msgList: [{msg: 'hello'},{msg: 'world'}]
}
})
Mustache 语法的格式
把 data 中的数据绑定到页面中渲染,使用 Mustache 语法 (双大括号) 将大变量包起来即可。语法格式为:
wxml
<view>{{ 要绑定的数据名称 }}</view>
应用场景
-
绑定内容
-
- 动态绑定内容形式: {{ }}
-
绑定属性
-
- 首先在 data 中写入一个 imgSrc
-
- 然后在 html 中写入 <image src=“{{ imgSrc }}”> </image>
-
- 可设置 mode
-
运算 (三元运算、算数运算等)
-
- <view> {{ randomNumber >= 5 ? " 大于5 " : “小于5” }} </view>
-
- JS中支持函数Math 例如在data 中设置一个值 randomNum1: Math.random() * 10 ,则会生成一个随机数
支持的函数包括: Math.random().toFixed(2) .
生成一个带两位小数的随机数 , 例如 0.34 .
Mustache 中也可以写一些算数运算 .
事件绑定
事件是渲染层到逻辑层的通讯方式. 通过事件可以将用户在渲染层产生的行为, 反馈到逻辑层进行业务的处理 .
渲染层可以理解为是页面
逻辑层可以理解为是JS
Native (微信客户端)
小程序中常用的事件
tap 触摸后马上离开的事件,类似于 HTML 中的 click 事件.
- 绑定方式: bindtap 或 bind:tap
input 文本框的输入事件,文本框的输入事件
- 绑定方式: bindinput 或 bind:input
change 状态改变时触发, 状态改变时触发
- 绑定方式: bindchange 或 bind:change
事件对象的属性列表
当事件回调触发的时候 , 会受到一个事件对象event , 它的详细属性如下表所示 :
类型 | 属性 | 介绍 |
---|---|---|
type: | String | 事件类型. |
timeStamp: | Integer | 页面打开触发事件所经过的毫秒数. |
target: | Object | 触发事件的组件的一些属性值集合. |
currentTarget | Object | 当前组件的一些属性值集合. |
detail | Object | 额外的信息. |
touches | Array | 触发事件,当前停留在屏幕中的触摸点信息的数组. |
changedTouched | Array | 触摸事件,当前变化的触摸点信息的数组. |
demo
HTML
<view class="tailedge">
个人电话:
<text selectable> {{telphone}} </text>
<button type="default" bindtap="btnTapHandler" >微信催促</button>
</view>
JS
Page({
btnTapHandler(e){
console.log("already post message"),
console.log(e)
},
/**
* 页面的初始数据
*/
data: {
telphone: '15135151098',
},
购买货物按钮
<view> 数量:{{goodsOne}} </view>
<button class="goodsbutton" mode="primary" size="mini" bindtap="ChangeCountGoodsOneReduce">减少</button>
<button class="goodsbutton" mode="primary" size="mini" bindtap="ChangeCountGoodsOnePlus">购买</button>
ChangeCountGoodsOnePlus(){
this.setData({
goodsOne: this.data.goodsOne + 1
})
// goodsOne: this.data.goodsOne + 1
},
ChangeCountGoodsOneReduce(){
if (this.data.goodsOne == 0){
console.log("pass")
}else{
this.setData({
goodsOne: this.data.goodsOne - 1
// goodsOne: this.data.goodsOne + 1
})
}
},
data: {
telphone: '15135151098',
goodsOne: 0
},
事件传参
不能在绑定事件的同时为事件处理函数传递参数.
<button type="primary" bindtap="btnTap2" data-info="{{2}}"></button>
如果不加 {{ }} 括号的话, 则会为str 类型, 加花括号就是 int 类型了
btnTap2(e){
console.log(e)
},
在target 属性中,可以看到 dataset 属性的 info 属性 为传参的值
事件传参
btnTap2(e){
this.setData({
goodsOne: this.data.goodsOne + e.target.dataset.info,
})
},
将count 的数值于传参的数值相加
抓取 input 值
<input bindinput="inputHandler"></input>
inputHandler(e){
console.log(e.detail.value)
},
实现文本框和 data 之间的数据同步
实现步骤:
① 定义数据
② 渲染结构
③ 美化样式
④ 绑定 input 事件处理函数
HTML
<view size="mini">
预留电话:
<input value="{{msg}}" bindinput="inputHandler"></input>
</view>
JS
data: {
telphone: '15135151098',
goodsOne: 0,
msg: "这里填入信息"
},
inputHandler(e){
console.log(e.detail.value),
this.setData({
msg: e.detail.value,
})
},
CSS
input {
border: 1px solid #eee;
margin: 5px;
padding: 5px;
border-radius: 3px;
}
条件渲染
AppData中可以修改 type 的值
HTML , 根据标签显示列表
<view wx:if="{{type === 1}}">
预留电话:
<input value="{{msg}}" bindinput="inputHandler"></input>
</view>
<view wx:elif="{{type === 2}}">
预留微信:
<input value="{{msg}}" bindinput="inputHandler"></input>
</view>
<view wx:elif="{{type === 3}}">
预留地址:
<input value="{{msg}}" bindinput="inputHandler"></input>
</view>
<view wx:else>保密</view>
使用block能够隐藏原来的 view ,在 html 中隐藏
<block wx:if="{{type === 1}}">
预留电话:
<input value="{{msg}}" bindinput="inputHandler"></input>
</block>
<block wx:elif="{{type === 2}}">
预留微信:
<input value="{{msg}}" bindinput="inputHandler"></input>
</block>
<block wx:elif="{{type === 3}}">
预留地址:
<input value="{{msg}}" bindinput="inputHandler"></input>
</block>
<block wx:else>保密</block>
也可以使用,判断一个True或者False时,去选择是否隐藏 view
如果为True 则隐藏, 还支持 display: none/block 控制元素的显示和隐藏
<view hidden="{{flag}}">
xxx
</view>
hidden 是通过加样式来进行显示或隐藏
wx:if 是以创建和移除元素的方式进行控制元素的展示于隐藏
使用建议
- 频繁切换时,建议使用 hidden . 因为只有 True 和 False 去控制
- 控制条件复杂时,建议使用 wx:if ,可以有 elif 多种条件控制
列表渲染
通过 wx:for 可以根据指定的数组,循环渲染重复的组件结构,语法实例如下:
wxml
<view wx:for"{{array}}" >
索引是: {{index}} 当前项是: {{item}}
</view>
js
data: {
telphone: '15135151098',
/**
* 个人电话,接受各类合作
*/
goodsOne: 0,
msg: "这里填入信息",
type: 1,
flag: true,
array: ['苹果','华为','小米']
},
可以将默认的 index 和 item 换个名字进行识别展示:
例如:
<view wx:for="{{array}}">
索引是:{{index}}, item项是: {{item}}
</view>
<view>~~~~~~~~~~~~~</view>
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
索引是:{{idx}}, item项是: {{itemName}}
</view>
这个时候虽然可以实现效果,但是会报一个警告缺少key的错误.
进行修改以下就可以了
<view wx:for="{{array}}" wx:key="index">
索引是:{{index}}, item项是: {{item}}
</view>
<view>~~~~~~~~~~~~~</view>
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName" wx:key="idx">
索引是:{{idx}}, item项是: {{itemName}}
</view>
什么是WXSS模板样式
WXSS具有 CSS 大部分特性, 同时 WXSS 还对 CSS 进行了扩充及修改,以适应微信小程序的开发.
与 CSS 相比, WXSS 扩展的特性有
- rpx 尺寸单位
- @Import 样式导入
wxss 不支持一些选择器样式规则,但是支持通用的样式规则
WXSS 模板样式 - rpx
什么是 rpx 尺寸单位
rpx (responsive pixel) 是微信小程序独有的, 用来解决屏适配的尺寸单位.
rpx 的实现原理
rpx 的实现原理非常简单: 鉴于不同设备屏幕的大小不同, 为了实现屏幕的自动适配, rpx 把所有设备的屏幕, 在宽度上等分为 750 份 ( 既:当前屏幕的总宽度为 750rpx )
- 在较小的设备上, 1rpx 所代表的宽度较小
- 在较大的设备上, 1rpx 所代表的宽度较大
rpx专门用来实现屏幕适配的一种实现
rpx 和 px 之间的 单位换算
在 iPhone6 上, 屏幕宽度为 375px , 共有 750 个物理像素, 等分为 750rpx. 则:
750rpx = 375px = 750 物理像素
1 rpx = 0.5px = 1 物理像素
1rpx 等于不同的 px
因为每个手机的宽度不一样
举例:
iphone5 1rpx = 0.42px
iphone6 1rpx = 0.5px
换算方式 屏幕宽度 除以 750
WXSS 模板样式 - 样式导入
- @import 的语法格式
@import 后面跟需要导入的外联样式表的相对路径, 用 ; 号表示语句结束. 实例如下:
.small-p {
padding:5px;
}
@import "common.wxss"
.middle-p {
padding:15px;
}
首先在顶级目录创建一个目录 common
然后在该目录下创建一个文件 common.wxss
写一个公共的css
.username{
color: red;
}
然后尝试在其他的wxss中导入
例如使用list.wxss中进行导入
头部写入
@import "/common/common.wxss";
然后在list.wxml中写入一个 view 进行测试 - 发现显示的字变成了红色
<view class="username"> 注意事项: {{msg}}</view>
全局设置
如果在 app.wxss
中进行设置,则会对所有的块进行渲染
view {
padding: 10rpx;
margin: 10rpx;
background-color: lightskyblue;
}
<!--pages/list/list.wxml-->
<!-- <text class="headcenter" id="head">WeChat</text> -->
<rich-text class="BT" nodes="<h1 style='color: red;'> 个人网页 </h1>"> </rich-text>
<view wx:for="{{array}}" wx:key="index">
索引是:{{index}}, item项是: {{item}}
</view>
<view>~~~~~~~~~~~~~</view>
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName" wx:key="idx">
索引是:{{idx}}, item项是: {{itemName}}
</view>
<view> 数量:{{goodsOne}} </view>
<button class="goodsbutton" type="primary" size="mini" bindtap="ChangeCountGoodsOnePlus">购买</button>
<button class="goodsbutton" type="warn" size="mini" plain bindtap="ChangeCountGoodsOneReduce">减少</button>
<view></view>
<button type="primary" mode="default" bindtap="btnTap2" data-info="{{10}}" size="mini">购买一组</button>
<scroll-view class="container1" scroll-y>
<view>A</view>
<view>B</view>
<view>C</view>
</scroll-view>
<!-- 轮播图区域 -->
<!-- indicator-dots 属性: 显示面板指示点 -->
<!-- indicator-active-color 当前选中的知识点颜色 -->
<!-- autoplay 自动切换,默认五秒 interval() 会设置默认时间,单位为毫秒,1sec = 1000ms -->
<!-- 衔接滑动 circular -->
<swiper class="swiper-container" indicator-dots indicator-active-color="gray" indicator-active-color="black" autoplay interval="5000" circular>
<!-- 第1项 -->
<swiper-item>
<view class="item">石头</view>
</swiper-item>
<!-- 第2项 -->
<swiper-item>
<view class="item">剪刀</view>
</swiper-item>
<!-- 第3项 -->
<swiper-item>
<view class="item">布</view>
</swiper-item>
<swiper-item>
<image src="/images/1.png" mode="aspectFill"></image>
</swiper-item>
</swiper>
<view>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</view>
<!-- <button size="mini" >默认按钮</button> -->
<!-- <view class="tail-view" bindtap="outerHandler"> -->
<button class="tailbutton" type="primary" size="mini" bindtap="inputType" data-info="{{1}}">电话</button>
<button class="tailbutton" type="warn" plain size="mini" bindtap="inputType" data-info="{{2}}">微信</button>
<button class="tailbutton" type="primary" size="mini" bindtap="inputType" data-info="{{3}}">地址</button>
<!-- </view> -->
<view>~~~~~~~~~~~~~~{{type}}~~~~~~~~~~~~~~~~~~~~</view>
<view wx:if="{{type === 1}}">
预留电话:
<input value="{{msg}}" bindinput="inputHandler"></input>
</view>
<view wx:elif="{{type === 2}}">
预留微信:
<input value="{{msg}}" bindinput="inputHandler"></input>
</view>
<view wx:elif="{{type === 3}}">
预留地址:
<input value="{{msg}}" bindinput="inputHandler"></input>
</view>
<block wx:else>保密</block>
<view class="tailedge">
商家电话:
<text selectable> {{telphone}} </text>
<button type="default" bindtap="btnTapHandler" >微信催促</button>
</view>
<view class="username"> 注意事项: {{msg}}</view>
局部样式
只会作用于当前页面
注意:
-
①当局部样式和全局样式冲突时, 根据就近原则, 局部样式会 覆盖 全局样式.
-
②当局部样式的 权重大于或等于 全局样式的权重时, 才会覆盖全局的样式.
可以对第几个匹配到的块进行渲染,例如:
view:ntp-child(1) {
backgroud-color: lightskyblue;
}
权重问题:
权重大 0,1,1
权重小 0,0,1
如何查看这个渲染函数的权重是多少,在微信开发者工具,鼠标指向该函数,则会自动显示该函数的权重值
全局配置文件及常用的配置项
小程序根目录下的 app.json 文件是小程序的全局配置文件. 常用的配置项如下:
① pages
- 纪录当前小程序所有页面的存放路径
② window - 全局设置小程序窗口的外观
③ tabBar - 设置小程序底部的 tabBar 效果
④ style - 是否启用新版的组件样式
全局配置 - window
1.小程序窗口的组成部分
- 导航栏区域
- 背景区域
- 页面的主题区域
了解 window 配置
属性名 | 类型 | 串值 | 说明 |
---|---|---|---|
navigationBarTitleText | String | 字符串 | 导航栏标题文字内容 |
navidationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如 #000000 |
navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持 black/white |
backgroundColor | HexColor | #ffffff | 串口的背景色 |
backgroundTextStyle | String | dark | 下拉loading的样式,仅支持 dark/light |
enablePullDownRefresh | Boolean | false | 是否全局开启下拉刷新 |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为px |
如何设置导航栏的标题
设置步骤:
app.json -> window -> navigationBarTitleText
{
"pages": [
"pages/list/list",
"pages/index/index",
"pages/logs/logs"
],
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "MyselfSupermarket",
"navigationBarBackgroundColor": "#3b9b5b"
},
"style": "v2",
"componentFramework": "glass-easel",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents"
}
导航栏的标题颜色
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "水上漂商铺",
"navigationBarBackgroundColor": "#3b9b5b",
"navigationBarTextStyle":"white"
},
全局开启下拉刷新功能
概念: 下拉刷新
是移动端的专有名词, 指的是通过手指在屏幕上的下拉滑动操作, 从而 重新加载页面数据
的行为.
🤣设置步骤: app.json -> window -> 把 enablePullDownRefresh 的值设置为 true
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "水上漂商铺",
"navigationBarBackgroundColor": "#3b9b5b",
"navigationBarTextStyle":"white"
"enablePullDownRefresh ":true
},
默认不开启下拉刷新
.下拉刷新时候会显示定义的背景
注:会作用于小程序的每一个页面,全局开启下拉刷新
下拉刷新的背景色
自定制背景色
设置下拉刷新时窗口的背景色
backgroundColor
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "水上漂商铺",
"navigationBarBackgroundColor": "#3b9b5b",
"navigationBarTextStyle":"white"
"enablePullDownRefresh ":true,
"backgroundColor": "#efefef"
},
设置下拉刷新时的 Loading 的位置
当开启下拉刷新后, 默认窗口的 loading 样式为白色, 如果要更改loading 样式的效果, 设置步骤为 app.json
-> window
-> 为 backgroundTextStyle
指定 dark
值. 效果如下:
下拉刷新时,三个小圆点的颜色,白色和黑色.
"backgroundTextStyle":"dark",
设置上拉触底的距离
概念: 上拉触底
是移动端的专有名词, 通过手指在屏幕上的上拉滑动操作, 从而 加载更多数据
的行为
设置步骤: app.json -> window -> 为 onReachBottomDistance 设置新的数值
注意: 默认距离为 50px , 如果没有特殊要求,建议使用默认值即可.
"window": {
"backgroundTextStyle":"dark",
"navigationBarTitleText": "水上漂商铺",
"navigationBarBackgroundColor": "#3b9b5b",
"navigationBarTextStyle":"white",
"enablePullDownRefresh":true,
"backgroundColor": "#efefef",
"onReachBottomDistance": 100
},
全局配置 - tabBar
说明是tabBar
上端或者下端的可选择页面,用于实现多页面切换
- 底部 tabBar
- 顶部 tabBar
注意:
- tabBar 中只能配置最少 2 个,最多 5 个tab页签
- 当渲染顶部 tabBar 时, 不显示 icon , 只显示文本
tabBar 的6个组成部分
①backgroundColor: tabBar 的背景色
②selectediconPath: 选中时的图片路径
③borderStyle: tabBar 上边框的颜色
④iconPath: 未选中时的图片路径
⑤selectedColor: tab上的文字选中时的颜色
⑥color: tab上文字默认的(未选中)颜色
控制不同区域的样式,或者图片.
tabBar 效果
app.json 和 window 平级
配置tabBar
"tabBar": {
"list": [
{
"pagePath": "pages/list/list",
"text": "list"
},
{
"pagePath": "pages/index/index",
"text": "index"
},
{
"pagePath": "pages/test/test",
"text": "test"
}
]
},
属性 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
position | String | 否 | bottom | tabBar的位置,仅支持 bottom/top |
torderStyle | String | 否 | black | tabBar上边框的颜色,仅支持 black/white |
color | HexColor | 否 | tab上文字的默认(未选中)颜色 | |
selectedColor | ~ | ~ | tab上的文字选中的颜色 | |
backgroundColor | HexColor | 否 | tabBar的背景色 | |
list | Array | 是 | tab页签的列表,最少2最大5 |
每个tab项的配置选项
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
pagePath | String | 是 | 页面路径,页面必须在pages中预定义 |
text | String | 是 | tab上显示的文字 |
iconPath | String | 否 | 未选中时的图标路径;当position为top时,不显示icon |
selectediconPath | String | 否 | 选中时的图标路径;当position为top时,不显示icon |
为 tabBar 配置选项
在 app.json “pages” 写入新增的页面, 会自动生成相关的 四 个文件
配置 tabBar选项
① 打开 app.json 配置文件, 和pages , windows 平级, 新增 tabBar 节点
② tabBar 节点中, 新增 list 数组, 这个数组中存放的, 是每个 tab 项的配置对象
③ 在 list 数组中, 新增每一个 tab 项的配置对象.对象中包含的属性如下:
- pagePath
- text
- iconPath
- selectediconPath
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"text": "index"
},
{
"pagePath": "pages/list/list",
"text": "list",
"iconPath": "/images/tabs/darkList.png",
"selectedIconPath": "/images/tabs/lightList.png"
},
{
"pagePath": "pages/test/test",
"text": "test"
},
{
"pagePath": "pages/home/home",
"text": "home",
"iconPath": "/images/tabs/darkHome.png",
"selectedIconPath": "/images/tabs/lightHome.png"
}
]
},
如果是tabBar的页面就必须放在 pages 的头部位置
小程序中的页面配置
小程序中,每个页面都有4个配置文件.
每个页面的 .json 配置文件, 用来对 当前页面
的窗口外观,页面效果等进行配置.
页面配置 和 全局配置 的关系
小程序中, app.json 中的 window 节点, 可以全局配置
小程序中 每个页面的窗口表现.
如果某个小程序的页面 想要拥有特殊的窗口表现, 此时, “页面级别的 .json 配置文件” 就可以实现这种需求.
注意: 当页面配置和全局配置冲突时,根据 就近原则, 最终的效果以页面配置为准.
页面配置和全局配置的关系
当页面和全局冲突时,根据就近原则,最终的效果以页面配置为准.
页面配置中常用的配置项
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
navigationBarBackgroundColor | HexColor | #000000 | 当前页面导航栏背景颜色,如 #000000 |
navigationBarTextStyle | String | white | 当前页面导航栏标题颜色,仅支持 black/white |
navigationBarTitleText | String | 当前页面导航栏标题文字内容 | |
backgroundColor | HexColor | #ffffff | 当前页面窗口的背景色 |
backgroundTextStyle | String | dark | 当前页面下拉 loading 的样式,仅支持 dark/light |
enablePullDownRefresh | Boolean | false | 是否为当前页面开启下拉刷新的效果 |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为 px |