文章目录
02-小程序-模板与配置
一、wxml 模板语法 - 数据绑定
拓展:在微信开发者工具中,自己创建的文件夹
1、使用的基本原则
① 在 data 中定义数据
② 在 wxml 中使用数据
是不是和我们vue中很像啊!说白就是很像。数据双向绑定!
2、在 data 中定义页面的数据
在页面对应的 js 文件中,把数据定义到 data 对象中即可;
//index.js
// 1、在 js 文件中 data 数据项中声明我们的数据
Page({
data: {
info: 'hello world'
}
})
3、 Mustache 语法的使用
把 data 中的数据绑定到页面中渲染,使用 Mustache 语法 就是vue 中的 模板语法 (双花括号) 将变量包裹起来即可。
- 下面这里是动态的绑定内容
<!--index.wxml-->
<!-- 在我们的 wxml 文件中 标签内简单的使用了 该数据项 -->
<view>{{ info }}</view>
4、MUstache 语法的主要使用场景:
- 绑定属性
index.js
Page({
data: {
imgSrc: '../images/images.png'
}
})
index.wxml
<!--
注意点:这里我们不需要和vue中一样,v-bind:src的写法
→ 这里只需使用 {{}} 即可
-->
<image src="{{ imgSrc }}" mode=""/>2
- 绑定内容
index.js
Page({
data: {
randomNum1: Math.random() * 10
}
})
index.wxml
<view>{{ randomNum1 >= 5 ? '数字大于或等于5' : '数字小于5'}}</view>
- 运算(三元计算、算数运算等)
index.js
Page({
data: {
// 生成 [0-1)的小数,通过 toFixed(2)方法保留两位小数
randomNum2: Math.random().toFixed(2)
}
})
index.wxml
<!-- 运算后的结果渲染 -->
<view>{{ randomNum2 * 100 }}</view>
- 总结:所有有结果 或者 又返回结果的都可以通过 {{ }} 来渲染。
二、wxml 模板语法 - 事件绑定
1、什么是事件
事件是 渲染层到逻辑层的通讯方式,通过事件可以将用户在渲染层产生的行为,反馈到我们逻辑层进行业务的处理。
2、小程序中常用的事件
类型 | 绑定方式 | 事件描述 |
---|---|---|
tap | bindtap 或 bind:tap | 手指触摸后马上离开,类似于 click事件 |
input | bindinput 或 bind:input | 文本框的输入事件 |
change | bindchange 或 bind:change | 状态修改时触发 |
3、事件对象 的 常用 属性列表
- 当事件被触发的时候,会收到一个 事件对象 event, 他会有详细的事件信息
属性 | 类型 | 说明 | |
---|---|---|---|
target | Object | 触发事件的组件的一些属性值集合 | |
detail | Object | 额外的信息 | |
type | String | 事件类型 | |
timeStamp | Integet | 页面打开到触发事件所经过的毫秒数 | |
currentTarget | Object | 当前组件的一些属性值集合 | |
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 | |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
4、target 和 currentTarge 属性的区别
- target 是触发该事件的 源头组件, 而 currentTarget 则是 当前事件所绑定的组件,看下面例子。
<!-- target 和 currentTarget 属性的区别 -->
<view bindtap="onFn" class="outer-view">
<button type="primary">按钮</button>
</view>
说明:
点击内部的按钮的时候,点击事件以 冒泡的方式向外部扩散,也会触发外层的 view 的 tap 事件处理函数。
此时,相对于view组件来说:
- e.target 指向的是触发事件的源头组件,因此,e.target 是内部的按钮组件
- e.curretTarget 指向的是当前正在触发事件的那个组件,因此,e.currentTarget 是当前 view组件
一般情况下,我们多数只会用到e.target事件属性。
5、bindtap 的语法格式
在小程序中,不存在 html 中的 onclick鼠标点击事件,而是通过 tap 事件来响应用户的触摸行为。
① 通过 bindtap ,可以为组件绑定 tap 触摸事件
语法:
① 通过 bindtap ,为组件绑定一个触摸事件
<!-- 事件绑定-->
<button type="primary" bindtap="btnTapHandler">按钮</button>
② 在页面 js 文件中定义对应的事件处理函数,(event 简写为 e)
// 定义按钮的事件处理函数
btnTapHandler (e) {
console.log(e)
}
三、wxml 模板语法 - 事件传参与数据同步
1、在事件处理函数中操作data里面的数据
语法:
this.setData(dataObject)
this.setData({
data: data + 1
})
通过该方法,可以给页面 data 数据重新赋值。
代码示例
// index.wxml
<button type="primary" bindtap="CountChange">+1</button>
// index.js
// data数据项
data: {
count: 0
}
this.setData({
// this.data拿到data数据里面的 count值
count: this.data.count + 1
})
},
2、事件函数传参
小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传递参数;
如下:错误示例
<button type="primary" bindtap="PassParameter(123)">传参</button>
- 上面 passParameter(123)是一个函数名,他不会和vue一样。小括号里面的依旧会被认为是名字哦!因为小程序里面只要是被引号括起来的统一认为是 函数名
到底该如何传递呢?
为组件提供 data-* 自定义属性传参
其中 * 代表的是参数的名字,如下所示:
<!-- 事件传参 -->
<button type="primary" bindtap="PassParameter" data-info="{{ 520 }}">传参</button>
// 获取参数使用 e.target.dataset.参数名
PassParameter (e) {
this.setData({
// 修改count的值
count: this.data.count + e.target.dataset.info
})
}
说明:
info: 会被解析为 参数的名字
数值 2 会被解析为参数值
e.target.dataset 可以理解为是事件对象的形参,后面跟上参数名
注意点:{{}} 括起来的是数字,不用则视为字符串。
3、bindinput的语法格式
在小程序中,通过 input 事件来响应输入框的输入事件,语法格式如下:
① 通过 bindinput,可以为文本框绑定输入事件:
<!-- 输入事件 -->
<input type="text" bindinput="InputChange" placeholder="请输入姓名"/>
② 在 js 文件中 定义事件处理函数
// bindinput事件
InputChange (e) {
// 拿到文本框变化后的值
console.log(e.detail.value)
},
e.detail.value得到的是事件对象的信息(value值)
4、 实现文本框和 data 之间的数据同步
实现步骤:
- 定义数据
- 渲染结构
- 美化样式
- 绑定 input 事件处理函数
代码示例:
<!-- 输入框值的双向绑定 -->
<input type="text" value="{{ msg }}" bindinput="handleInput"/>
第二步:
// 数据的双向绑定
handleInput (e) {
this.setData({
// 通过 e.detail.value 实时拿到输入框的值,同步data中的数据
msg: e.detail.value
})
// 函数触发后,获取data 中的msg数据,就是输入框实施的value值
console.log(this.data.msg)
},
注意:就是结构上的value需要绑定我们data中的数据变量,然后就是在通过输入事件监听数据的变化,然后通过e.detail.value修改 data 数据中的值,从而实现数据双向绑定。
四、wxml 模板语法 - 条件渲染
1、wx:if
-
在小程序中,使用:
wx: if="{{渲染条件}}"
来判断是否需要渲染该代码块: -
也可以使用
wx:elif wx:else
来添加else判断:
代码示例:
// 条件渲染
Page({
data: {
type: 1
}
})
<!-- index.wxml -->
<view wx:if="{{ type === 1 }}">男</view>
<view wx:elif="{{ type === 2 }}">女</view>
<view wx:else>保密</view>
通过条件渲染,从而实现按需渲染。
2、结合< block >使用 wx:if 的渲染
如果我们需要一次渲染多个组件的展示于隐藏,就可以使用到标签了,他将所有需要条件渲染的组价包裹起来,然后,我们直接在 标签上使用 wx:if 进行控制。
- 代码示例:
Page({
data: {
type: 1
}
})
<!-- 通过block标签,控制多个组件的展示和隐藏 -->
<block wx:if="{{ type === 1 }}">
<view>1</view>
<view>2</view>
<view>3</view>
</block>
- 需要注意的是,block并不是一个组件,它只是一个包裹性的容器,不会在页面中,做任何渲染。
- 不会被渲染标签,其他的可以但会被许然然。
3、hidden控制显示于隐藏
在小程序中,直接使用 hidden=“{{}}” 也能直接控制元素的显示于隐藏(通过 true 或 false)
代码示例:
<!-- hidden 控制显示和隐藏 (和 vue中的 v-Show一样) -->
<button hidden="{{ false }}" type="primary">按钮</button>
4、wx:if 和 hidden 的区别
① 执行原理不同:
- wx:if : 动态创建和移除元素的方式,控制元素的显示和隐藏
- hidden: 以切换样式的方式,控制元素的显示和隐藏(display: none/block)
应用场景:和 vue一样,频繁切换使用 hidden,需要条件渲染的时候使用wx:if。
总结: hidden就是在控制结构样式,而wx:if控制的是创建结构或者移除结构。
5、wx:for的使用以及wx:key
渲染数组列表的时候,我们可以直接使用 wx:for实现,和vue中的v-for一样哦!
data数据代码:
data: {
arr1: ['iQOO', '华为', '小米'],
userInfo: [
{id: 1, name: '张三'},
{id: 2, name: '李四'},
{id: 3, name: '王五'}
]
}
- wx:for 代码实例:
<!-- 列表渲染 wx:for 和 vue中的 v-for思路一样的-->
<!-- 第一种用法 -->
<view wx:for="{{ arr1 }}">
索引号:{{ index}} → 元素内容: {{ item }}
</view>
<!-- 第二种用法: 使用wx:if-index/item 重命名名字 (很少使用) -->
<view wx:for="{{ arr1 }}" wx:for-index="ind" wx:for-item="LIst">
索引号:{{ ind}} → 元素内容: {{ LIst }}
</view>
- wx:key 代码示例:
<!-- wx:key的使用方法 -->
<view wx:for="{{ userInfo }}" wx:key="id">
姓名:{{ item.name }}
</view>
需要注意的是,wx:key 不需要使用 {{}}
- 有 id 使用 id ,没有则使用 index
五、wxss 模板样式
1、什么是wxss
wxss 是一套样式语言,用于美化 wxml 的组件样式,类似于网页开发中的 css。
2、wxss 和 css 的关系
wxss 具有 css 大部分的特性,同时,wxss 还对 css 进行了扩充和修改,以适应微信小程序的开发。
与 css 相比,wxss 拓展的特性有:
- rpx尺寸单位
- @import样式导入
这两个css中不能使用,同样的rem小程序中也不能使用。
3、rpx 尺寸单位
- 什么是rpx尺寸单位?
它是微信小程序独有的,用来解决屏幕适配的尺寸单位(和 css 中的 rem媒体查询一样)
原理:
rpx: 鉴于不同的设备大小不同,为了实现自动适配,rpx把所有设备的屏幕,在宽度上等分为750份(即当前屏幕的总宽度为750rpx)
- 在较小的设备上, 1rpx 所代表的宽度较小
- 在较大的设备上, 1rpx 所代表的宽度较大
小程序在不同设备上运行的时候,会自动把 rpx 的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配。
单位换算:官方定义使用iphone6上,1px = 0.5 rpx
因为 屏幕会被分为 750rpx 而 苹果6 正好 375px。
设备 | rpx换算px(屏幕宽度 / 750) | px换算rpx(750 / 屏幕宽度) |
---|---|---|
iphone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iphone6 | 1rpx = 0.5px | 1px = 2rpx |
iphone6 plus | 1rpx = 0.552px | 1px = 1.81px |
官方建议:开发微信小程序,设计可以使用iPhone6 作为视觉稿的标准。
例如:宽度 100px, 高度20px。使用rpx就是, 200rpx , 40rpx。
4、@import样式导入
语法格式
@import 后跟需要导入的外联样式的相对路径,用 ; 表示语句结束。如下所示:
/** common。wxss**/
/* 导入样式,然后标签直接使用该样式表中的样式 */
@import "/common/common.wxss";
5、全局样式和局部样式
顾名思义:全局所用于全部页面,局部只限于当前页面。
① app.wxss中则就会作用到全局。
② 页面.wxss 文件中定义的样式为局部样式,只作用于当前页面。
注意点:
- 当局部样式和全局样式冲突的时候,根据
就近原则
,局部样式会覆盖全局样式。 - 当局部样式的权重大于或等于全局样式的时候,才会覆盖全局样式(全中小的话则就不会覆盖)
/* 权重相等的情况下,局部样式于全局样式冲突,则会覆盖重复的样式 */
view {
background-color: lightpink;
}
六、全局配置
小程序根目录下的app.json
文件是小程序的全局配置文件,常用的配置如下:
app.json配置文件,所管理的全局的文件有:
① pages
- 记录当前小程序所有页面的存放路径
② window
- 全局设置小程序窗口外观
③ tabBar
- 设置小程序底部的 tabBar 效果
④ style
- 是否启用新版的样式组件
01 全局配置 - window
1.1配置导航栏的标题
步骤:app.json → window → navigationBarText
"window": {
"navigationBarTitleText": "最那不过坚持",
}
1.2设置导航栏的背景色
步骤:app.json → window → navigationBarBackgroundColor
以十六进制色为要求哦!
"window": {
"navigationBarBackgroundColor": "#2b4b6b",
}
需要注意的是,局部和全局配置文件的冲突哦!
1.3设置导航栏的标题颜色
步骤: app.json → window → navigationBarTextStyle
"window": {
"navigationBarTextStyle": "white,
}
需要注意的是,标题颜色可选值 只有 black and white.
1.4全局开启下拉刷新功能
下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而实现重新加载页面数据的行为。
步骤: app.json → window → 把 enablePullDownRefresh 设置为 true
就开启了, false 则是不开启。
"window": {
"enablePullDownRefresh": true
}
true 开启, false 关闭
注意:这里在实际开发中,并不是所有的页面需要开启下拉加载效果,所以这里建议配置在局部页面配置文件中。
1.5设置下拉刷新时窗口的背景色
默认的背景色是白色,如果想要自定义颜色的话
步骤:app.json → window → 为backgroundColor 指定十六进制 的颜色值
"window": {
"backgroundColor": "#efefef"
}
1.6设置下拉刷新时 loading 的样式
步骤: app.json → window → 为 backgroundTextStyle 指定 dark值
(灰色)
"window": {
"backgroundTextStyle": "dark",
}
默认值就是light 白色,这里设置为dark 灰色。
注意这里就只能设置这两种颜色(效果图就是上面的图片)
1.7设置上拉触底的距离
上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而实现加载更多的数据行为。
步骤: app.json → window → 为 onReschBottomDistance 设置新的值
(默认值为:50px) 单位默认省略哦!
- 如果有特殊要求,在进行设置。
"window": {
"onReachBottomDistance": 50
}
实际开发不建议修改,使用默认之即可,特殊需求除外。
02 全局配置 - tabBar
1.1什么是tabBar
tabBar 是移动端常见的页面效果,用于实现多页面的快速切换。小程序中通常将其分为:
- 底部 tabBar
- 顶部 tabBar
注意点:
- tabBar 中只能配置
最少 2个 最多 5个
tab标签 - 顶部的 tabBar ,不显示 icon 图标,只显示文本。
1.2 tabBar 的 6 个主成部分
1.3 tabBar 必备的配置项 list 列表
1.4 tabBar标签栏的实现
实现方式:
1、先配置页面路径
"pages": {
"pages/home/home",
"pages/message/message",
"pages/contact/contact",
},
"windows": {
},
"tabBar": {
}
2、app.josn全局配置文件中,与pages 和 window同级别创建一个 tabBar配置对象
"pages": {
},
"windows": {
},
"tabBar": {
"list": [
{
"pagePath": "pages/home/home",
"text": "首页",
"iconPath": "/images/tabs/home.png",
"selectedIconPath": "images/tabs/home-active.png"
},
{
"pagePath": "pages/message/message",
"text": "消息",
"iconPath": "/images/tabs/message.png",
"selectedIconPath": "images/tabs/message-active.png"
},
{
"pagePath": "pages/contact/contact",
"text": "联系我们",
"iconPath": "/images/tabs/contact.png",
"selectedIconPath": "images/tabs/contact-active.png"
}
]
},
"style": {
}
注意点:只要是 tabBar的页面路径,必须在前面,否则报错!
效果图如下:
1.5 全局配置和局部配置
小程序中,app.json 中的 window 节点,可以全局配置小程序中每个页面的窗口表现。
如果某些小程序页面想要 拥有特殊的窗口表现,此时,页面级别的 .json配置文件,就可以实现这种需求了。
注意:当页面配置与全局配置 冲突时,根据就近原则
,最终的效果以页面配置为准。
如上:我想要将消息页面的导航背景改为红色:
在massage.json局部配置文件中:
"navigationBarBackgroundColor": "#ff0000"
就近原则,直接覆盖掉全局配置的样式。
1.6页面局部配置项
局部配置文件配置页面:
massage.json配置中
{
"usingComponents": {},
"navigationBarBackgroundColor": "#ff0000",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "消息页面",
"backgroundColor": "#ff0000",
"backgroundTextStyle": "light",
"enablePullDownRefresh": true
}
七、网络数据请求
1、xcx中网络请求的限制
出于 安全 和 性能 方面的考虑,小程序官方对 数据接口请求 有一些要求:
两点限制:
只能请求 HTTPS 类型的接口
必须将接口的域名添加到信任列表中
2、配置 request 合法域名
假设在自己的微信小程序中,希望请求https://www.escook.cn/
域名下的接口
此时就得配置域名接口:
配置步骤: 登录微信小程序管理后台 → 开发 → 开发设置 → 服务器域名 → 修改 request 合法域名
注意:一个月只能修改 5 次。且只支持https。
3、发起 GET 请求
调用微信小程序提供过的 wx.request()
方法,可以发起 GET 数据请求,如下所示:
<button bindtap="getInfo">发起GET请求</button>
// 发起 GET请求
getInfo () {
wx.request({
url: 'https://applet-base-api-t.itheima.net/api/get',
method: 'GET',
data: {
name: 'zs',
age: 20
},
success: (res) => {
console.log(res)
}
})
},
4、发起 POST 请求
调用微信小程序提供的 wx.request() 方法,可以发起 POST 数据请求,示例代码如下:
<button bindtap="postInof">发起POST请求</button>
// 发起 POST 请求
postInof () {
wx.request({
url: 'https://applet-base-api-t.itheima.net/api/post',
method: "POST",
data: {
name: 'ls',
age: 33
},
success: (res) => {
console.log(res.data)
}
})
},
5、如何在页面加载的时候请求数据
在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据。此时我们需要在页面的 onLoad 事件中调用获取数据的函数。
代码示例:
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// this是页面的实例,通过实例调用函数
this.getInfo()
this.postInof()
},
6、跳过 request 合法域名校验
当后端只提供了http协议接口的时候,我们开发又不能停止,所以,为了解决这个问题,我们得临时开启不校验开发环境域名请求
实现跳过 request 合法域名校验
- 注意: 跳过该 request 域名校验,仅限于开发与调试阶段。
7、关于 跨域 和 Ajax 的说明
跨域问题只存在于浏览器的Web开发中,由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序不存在跨域问题。
Ajax技术核心也是依赖于浏览器的,由于小程序的宿主环境是微信客户端,所以小程序中不能叫 发起Ajax请求,而是叫做发起网络数据请求
八、本地生活 - 案例
实现步骤:
- 新建项目并梳理项目结构
- 配置导航栏效果
- 配置 tabBar 效果
- 实现轮播图效果
- 实现九宫格效果
- 实现图片布局
1、新建项目并梳理项目结构
"pages":[
"pages/home/home",
"pages/message/message",
"pages/contact/contact"
],
2、配置导航栏效果
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#2b4b6b",
"navigationBarTitleText": "本地生活",
"navigationBarTextStyle":"white"
},
3、配置 tabBar 效果
"tabBar": {
"list": [
{
"pagePath": "pages/home/home",
"text": "首页",
"iconPath": "/images/tabs/home.png",
"selectedIconPath": "/images/tabs/home-active.png"
},
{
"pagePath": "pages/message/message",
"text": "消息",
"iconPath": "/images/tabs/message.png",
"selectedIconPath": "/images/tabs/message-active.png"
},
{
"pagePath": "pages/contact/contact",
"text": "联系我们",
"iconPath": "/images/tabs/contact.png",
"selectedIconPath": "/images/tabs/contact-active.png"
}
]
},
4、实现轮播图效果
4.1 获取轮播图数据
data: {
// 轮播图数据数据
swiperList: []
},
// 获取轮播图函数
getSwiperList () {
wx.request({
url: 'https://applet-base-api-t.itheima.net/slides',
method: 'GET',
success: (res) => {
this.setData({
swiperList: res.data
})
}
})
},
生命周期
onLoad(options) {
// 页面加载调用请求函数
this.getSwiperList()
},
4.2 轮播图结构样式的实现 - 渲染
- 结构 代码:
<!-- 轮播图区域 -->
<swiper indicator-dots circular autoplay>
<swiper-item wx:for="{{ swiperList }}" wx:key="id">
<image src="{{ item.image }}" mode=""/>
</swiper-item>
</swiper>
- 样式代码:
/* 限制大盒子的高度 */
swiper {
height: 350rpx;
}
swiper image {
width: 100%;
height: 100%;
}
5、实现九宫格效果
5.1 获取九宫格数据
data: {
// 轮播图数据数据
swiperList: [],
gridList: []
},
// 获取九宫格数据函数
getGridList() {
wx.request({
url: 'https://applet-base-api-t.itheima.net/categories',
method: 'GET',
success: (res) => {
this.setData({
gridList: res.data
})
}
})
},
onLoad(options) {
// 页面加载调用请求轮播图函数
this.getSwiperList()
// 页面加载调用请求九宫格函数
this.getGridList()
},
5.2 轮播图结构样式的实现 - 渲染
- 结构 代码:
<!-- 九宫格区域 -->
<view class="grid-max">
<view wx:for="{{ gridList }}" wx:key="id" class="grid-min">
<image src="{{ item.icon }}" mode=""/>
<text>{{ item.name }}</text>
</view>
</view>
- 样式代码:
/* 九宫格 */
.grid-max {
display: flex;
/* 一行排不下,允许换行 */
flex-wrap: wrap;
border-top: 1rpx solid #efefef;
border-left: 1rpx solid #efefef;
}
.grid-min {
display: flex;
/* 更改主轴方向 */
flex-direction: column;
align-items: center;
justify-content: center;
width: 33.33%;
height: 200rpx;
border-right: 1rpx solid #efefef;
border-bottom: 1rpx solid #efefef;
/* 宽度高度包含边框线,使得生效 */
box-sizing: border-box;
}
.grid-min image {
/* 每个小格子的宽和高都是 30px */
width: 60rpx;
height: 60rpx;
}
.grid-min text {
margin-top: 10rpx;
font-size: 24rpx;
}
6、实现图片布局
结构代码:
<!-- 图片区域 -->
<view class="img-box">
<image src="/images/link-01.png" mode="widthFix"/>
<image src="/images/link-02.png" mode="widthFix"/>
</view>
样式代码:
/* 底部图片区域 */
.img-box {
display: flex;
/* 平分 */
justify-content: space-around;
padding: 20rpx 10rpx;
}
.img-box image {
width: 45%;
}
总结 02
① 能够使用 wxml 模板语法渲染页面结构
wx:if wx:elif ex:else hidden wx:for wx:key
② 能够使用 wxss 样式美化页面结构
rpx 尺寸单位 、 @import 样式导入 、 全局样式和局部样式
③ 能够使用 app.json 对小程序进行全局配置
pages 、 window 、 tabBar 、 style
④ 能够使用 page.json 对小程序页面进行个性化配置
对单个页面进行个性化配置 就近原则
⑤ 能够知道如何 发起网络数据请求
wx.request({}) 方法 、 onLoad()页面加载事件