拓展:在微信开发者工具中,自己创建的文件夹
① 在 data 中定义数据
② 在 wxml 中使用数据
是不是和我们vue中很像啊!说白就是很像。数据双向绑定!
在页面对应的 js 文件中,把数据定义到 data 对象中即可;
//index.js
// 1、在 js 文件中 data 数据项中声明我们的数据
Page({
data: {
info: 'hello world'
}
})
把 data 中的数据绑定到页面中渲染,使用 Mustache 语法 就是vue 中的 模板语法 (双花括号) 将变量包裹起来即可。
<view>{{ info }}view>
index.js
Page({
data: {
imgSrc: '../images/images.png'
}
})
index.wxml
<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>
事件是 渲染层到逻辑层的通讯方式,通过事件可以将用户在渲染层产生的行为,反馈到我们逻辑层进行业务的处理。
类型 | 绑定方式 | 事件描述 |
---|---|---|
tap | bindtap 或 bind:tap | 手指触摸后马上离开,类似于 click事件 |
input | bindinput 或 bind:input | 文本框的输入事件 |
change | bindchange 或 bind:change | 状态修改时触发 |
属性 | 类型 | 说明 | |
---|---|---|---|
target | Object | 触发事件的组件的一些属性值集合 | |
detail | Object | 额外的信息 | |
type | String | 事件类型 | |
timeStamp | Integet | 页面打开到触发事件所经过的毫秒数 | |
currentTarget | Object | 当前组件的一些属性值集合 | |
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 | |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
<view bindtap="onFn" class="outer-view">
<button type="primary">按钮button>
view>
说明:
点击内部的按钮的时候,点击事件以 冒泡的方式向外部扩散,也会触发外层的 view 的 tap 事件处理函数。
此时,相对于view组件来说:
一般情况下,我们多数只会用到e.target事件属性。
在小程序中,不存在 html 中的 onclick鼠标点击事件,而是通过 tap 事件来响应用户的触摸行为。
① 通过 bindtap ,可以为组件绑定 tap 触摸事件
语法:
① 通过 bindtap ,为组件绑定一个触摸事件
<button type="primary" bindtap="btnTapHandler">按钮button>
② 在页面 js 文件中定义对应的事件处理函数,(event 简写为 e)
// 定义按钮的事件处理函数
btnTapHandler (e) {
console.log(e)
}
语法:
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
})
},
小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传递参数;
如下:错误示例
<button type="primary" bindtap="PassParameter(123)">传参</button>
到底该如何传递呢?
为组件提供 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 可以理解为是事件对象的形参,后面跟上参数名
注意点:{{}} 括起来的是数字,不用则视为字符串。
在小程序中,通过 input 事件来响应输入框的输入事件,语法格式如下:
① 通过 bindinput,可以为文本框绑定输入事件:
<!-- 输入事件 -->
<input type="text" bindinput="InputChange" placeholder="请输入姓名"/>
② 在 js 文件中 定义事件处理函数
// bindinput事件
InputChange (e) {
// 拿到文本框变化后的值
console.log(e.detail.value)
},
e.detail.value得到的是事件对象的信息(value值)
实现步骤:
代码示例:
<!-- 输入框值的双向绑定 -->
<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 数据中的值,从而实现数据双向绑定。
在小程序中,使用: 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>
通过条件渲染,从而实现按需渲染。
如果我们需要一次渲染多个组件的展示于隐藏,就可以使用到标签了,他将所有需要条件渲染的组价包裹起来,然后,我们直接在 标签上使用 wx:if 进行控制。
Page({
data: {
type: 1
}
})
<!-- 通过block标签,控制多个组件的展示和隐藏 -->
<block wx:if="{{ type === 1 }}">
<view>1</view>
<view>2</view>
<view>3</view>
</block>
在小程序中,直接使用 hidden=“{{}}” 也能直接控制元素的显示于隐藏(通过 true 或 false)
代码示例:
<!-- hidden 控制显示和隐藏 (和 vue中的 v-Show一样) -->
<button hidden="{{ false }}" type="primary">按钮</button>
① 执行原理不同:
应用场景:和 vue一样,频繁切换使用 hidden,需要条件渲染的时候使用wx:if。
总结: hidden就是在控制结构样式,而wx:if控制的是创建结构或者移除结构。
渲染数组列表的时候,我们可以直接使用 wx:for实现,和vue中的v-for一样哦!
data数据代码:
data: {
arr1: ['iQOO', '华为', '小米'],
userInfo: [
{id: 1, name: '张三'},
{id: 2, name: '李四'},
{id: 3, name: '王五'}
]
}
<!-- 列表渲染 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的使用方法 -->
<view wx:for="{{ userInfo }}" wx:key="id">
姓名:{{ item.name }}
</view>
需要注意的是,wx:key 不需要使用 {{}}
wxss 是一套样式语言,用于美化 wxml 的组件样式,类似于网页开发中的 css。
wxss 具有 css 大部分的特性,同时,wxss 还对 css 进行了扩充和修改,以适应微信小程序的开发。
与 css 相比,wxss 拓展的特性有:
这两个css中不能使用,同样的rem小程序中也不能使用。
原理:
rpx: 鉴于不同的设备大小不同,为了实现自动适配,rpx把所有设备的屏幕,在宽度上等分为750份(即当前屏幕的总宽度为750rpx)
小程序在不同设备上运行的时候,会自动把 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。
语法格式
@import 后跟需要导入的外联样式的相对路径,用 ; 表示语句结束。如下所示:
/** common。wxss**/
/* 导入样式,然后标签直接使用该样式表中的样式 */
@import "/common/common.wxss";
顾名思义:全局所用于全部页面,局部只限于当前页面。
① app.wxss中则就会作用到全局。
② 页面.wxss 文件中定义的样式为局部样式,只作用于当前页面。
注意点:
就近原则
,局部样式会覆盖全局样式。/* 权重相等的情况下,局部样式于全局样式冲突,则会覆盖重复的样式 */
view {
background-color: lightpink;
}
小程序根目录下的app.json
文件是小程序的全局配置文件,常用的配置如下:
app.json配置文件,所管理的全局的文件有:
① pages
② window
③ tabBar
④ style
步骤:app.json → window → navigationBarText
"window": {
"navigationBarTitleText": "最那不过坚持",
}
步骤:app.json → window → navigationBarBackgroundColor
以十六进制色为要求哦!
"window": {
"navigationBarBackgroundColor": "#2b4b6b",
}
需要注意的是,局部和全局配置文件的冲突哦!
步骤: app.json → window → navigationBarTextStyle
"window": {
"navigationBarTextStyle": "white,
}
需要注意的是,标题颜色可选值 只有 black and white.
下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而实现重新加载页面数据的行为。
步骤: app.json → window → 把 enablePullDownRefresh 设置为 true
就开启了, false 则是不开启。
"window": {
"enablePullDownRefresh": true
}
true 开启, false 关闭
注意:这里在实际开发中,并不是所有的页面需要开启下拉加载效果,所以这里建议配置在局部页面配置文件中。
默认的背景色是白色,如果想要自定义颜色的话
步骤:app.json → window → 为backgroundColor 指定十六进制 的颜色值
"window": {
"backgroundColor": "#efefef"
}
步骤: app.json → window → 为 backgroundTextStyle 指定 dark值
(灰色)
"window": {
"backgroundTextStyle": "dark",
}
默认值就是light 白色,这里设置为dark 灰色。
注意这里就只能设置这两种颜色(效果图就是上面的图片)
上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而实现加载更多的数据行为。
步骤: app.json → window → 为 onReschBottomDistance 设置新的值
(默认值为:50px) 单位默认省略哦!
"window": {
"onReachBottomDistance": 50
}
实际开发不建议修改,使用默认之即可,特殊需求除外。
tabBar 是移动端常见的页面效果,用于实现多页面的快速切换。小程序中通常将其分为:
注意点:
最少 2个 最多 5个
tab标签实现方式:
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的页面路径,必须在前面,否则报错!
效果图如下:
小程序中,app.json 中的 window 节点,可以全局配置小程序中每个页面的窗口表现。
如果某些小程序页面想要 拥有特殊的窗口表现,此时,页面级别的 .json配置文件,就可以实现这种需求了。
注意:当页面配置与全局配置 冲突时,根据就近原则
,最终的效果以页面配置为准。
如上:我想要将消息页面的导航背景改为红色:
在massage.json局部配置文件中:
"navigationBarBackgroundColor": "#ff0000"
就近原则,直接覆盖掉全局配置的样式。
局部配置文件配置页面:
massage.json配置中
{
"usingComponents": {},
"navigationBarBackgroundColor": "#ff0000",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "消息页面",
"backgroundColor": "#ff0000",
"backgroundTextStyle": "light",
"enablePullDownRefresh": true
}
出于 安全 和 性能 方面的考虑,小程序官方对 数据接口请求 有一些要求:
两点限制:
只能请求 HTTPS 类型的接口
必须将接口的域名添加到信任列表中
假设在自己的微信小程序中,希望请求https://www.escook.cn/
域名下的接口
此时就得配置域名接口:
配置步骤: 登录微信小程序管理后台 → 开发 → 开发设置 → 服务器域名 → 修改 request 合法域名
注意:一个月只能修改 5 次。且只支持https。
调用微信小程序提供过的 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)
}
})
},
调用微信小程序提供的 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)
}
})
},
在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据。此时我们需要在页面的 onLoad 事件中调用获取数据的函数。
代码示例:
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// this是页面的实例,通过实例调用函数
this.getInfo()
this.postInof()
},
当后端只提供了http协议接口的时候,我们开发又不能停止,所以,为了解决这个问题,我们得临时开启不校验开发环境域名请求
实现跳过 request 合法域名校验
跨域问题只存在于浏览器的Web开发中,由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序不存在跨域问题。
Ajax技术核心也是依赖于浏览器的,由于小程序的宿主环境是微信客户端,所以小程序中不能叫 发起Ajax请求,而是叫做发起网络数据请求
实现步骤:
"pages":[
"pages/home/home",
"pages/message/message",
"pages/contact/contact"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#2b4b6b",
"navigationBarTitleText": "本地生活",
"navigationBarTextStyle":"white"
},
"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"
}
]
},
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()
},
<!-- 轮播图区域 -->
<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%;
}
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()
},
<!-- 九宫格区域 -->
<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;
}
结构代码:
<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%;
}
① 能够使用 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()页面加载事件