掌握小程序页面开发基础
小程序页面由4个文件组成,它们具有相同的路径和文件名。
| 文件类型 | 必需 | 作用 |
|---|---|---|
| .js | 是 | 页面逻辑 |
| .wxml | 是 | 页面结构 |
| .wxss | 否 | 页面样式 |
| .json | 否 | 页面配置 |
1. 在 pages 目录下创建文件夹,如 home
2. 在 home 文件夹下创建4个文件:
- home.js
- home.wxml
- home.wxss
- home.json
3. 在 app.json 中注册页面路径// 在 app.json 中直接添加页面路径
{
"pages": [
"pages/index/index",
"pages/home/home" // 添加新页面
]
}
// 保存后,开发者工具会自动创建对应的文件<!-- pages/home/home.wxml -->
<view class="container">
<!-- 文本绑定 -->
<text>{{message}}</text>
<!-- 属性绑定 -->
<image src="{{imageUrl}}" />
<!-- 条件绑定 -->
<view wx:if="{{isShow}}">显示的内容</view>
<!-- 列表渲染 -->
<view wx:for="{{list}}" wx:key="id">
{{index}}: {{item.name}}
</view>
</view>
// pages/home/home.js
Page({
data: {
message: 'Hello World',
imageUrl: '/images/logo.png',
isShow: true,
list: [
{ id: 1, name: '项目1' },
{ id: 2, name: '项目2' },
{ id: 3, name: '项目3' }
]
}
})<!-- wx:if -->
<view wx:if="{{score >= 90}}">优秀</view>
<view wx:elif="{{score >= 60}}">及格</view>
<view wx:else>不及格</view>
<!-- hidden -->
<view hidden="{{!isVisible}}">内容</view>
// 区别:
// wx:if 会完全移除/添加元素
// hidden 只是切换 display 属性<!-- 基本用法 -->
<view wx:for="{{array}}" wx:key="id">
{{index}}: {{item.name}}
</view>
<!-- 自定义变量名 -->
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName" wx:key="id">
{{idx}}: {{itemName.name}}
</view>
<!-- 嵌套循环 -->
<view wx:for="{{groups}}" wx:key="groupId">
<text>{{item.groupName}}</text>
<view wx:for="{{item.members}}" wx:for-item="member" wx:key="memberId">
{{member.name}}
</view>
</view>/* rpx 是响应式像素单位 */
/* 规定:屏幕宽度 = 750rpx */
.box {
width: 750rpx; /* 屏幕宽度 */
height: 200rpx;
background: #07c160;
}
/* 在 iPhone 6 上(屏幕宽度375px):
750rpx = 375px
1rpx = 0.5px
200rpx = 100px
*//* 导入外部样式 */
@import "../common/common.wxss";
.container {
padding: 20rpx;
}
/* 全局样式 app.wxss */
page {
background-color: #f8f8f8;
font-size: 28rpx;
}
/* 页面样式会覆盖全局样式 *//* 支持的选择器 */
.class { } /* 类选择器 */
#id { } /* ID选择器 */
element { } /* 元素选择器 */
element, element { } /* 并集选择器 */
::after { } /* 伪元素 */
::before { } /* 伪元素 */
/* 不支持的选择器 */
/* 属性选择器、后代选择器等部分支持 */Page({
data: {
title: '页面标题'
},
// 生命周期函数
onLoad(options) {
// 页面加载时触发,一个页面只调用一次
// options 为页面跳转时传递的参数
console.log('页面加载', options)
// 适合:发起网络请求、初始化数据
},
onShow() {
// 页面显示/切入前台时触发
console.log('页面显示')
// 适合:刷新数据、开始动画
},
onReady() {
// 页面初次渲染完成时触发,一个页面只调用一次
console.log('页面渲染完成')
// 适合:获取节点信息、设置导航栏
},
onHide() {
// 页面隐藏/切入后台时触发
console.log('页面隐藏')
// 适合:停止动画、暂停音乐
},
onUnload() {
// 页面卸载时触发
console.log('页面卸载')
// 适合:清理定时器、取消请求
}
})Page({
// 下拉刷新
onPullDownRefresh() {
console.log('下拉刷新')
// 刷新数据
this.loadData()
// 停止下拉刷新
wx.stopPullDownRefresh()
},
// 上拉触底
onReachBottom() {
console.log('上拉触底')
// 加载更多数据
this.loadMore()
},
// 页面滚动
onPageScroll(e) {
console.log('页面滚动', e.scrollTop)
},
// 用户点击右上角分享
onShareAppMessage() {
return {
title: '分享标题',
path: '/pages/index/index',
imageUrl: '/images/share.jpg'
}
}
})<!-- WXML -->
<view>
<!-- bind 事件绑定(冒泡) -->
<button bindtap="handleTap">点击我</button>
<!-- catch 事件绑定(阻止冒泡) -->
<button catchtap="handleTap">点击我</button>
<!-- 传递参数 -->
<button bindtap="handleTap" data-id="123" data-name="test">
传递参数
</button>
</view>
// JS
Page({
handleTap(e) {
console.log('点击事件', e)
// 获取参数
const id = e.currentTarget.dataset.id
const name = e.currentTarget.dataset.name
console.log(id, name) // 123 test
}
})<!-- 点击事件 -->
<view bindtap="handleTap">点击</view>
<!-- 长按事件 -->
<view bindlongpress="handleLongPress">长按</view>
<!-- 触摸事件 -->
<view bindtouchstart="handleTouchStart">触摸开始</view>
<view bindtouchmove="handleTouchMove">触摸移动</view>
<view bindtouchend="handleTouchEnd">触摸结束</view>
<!-- 输入事件 -->
<input bindinput="handleInput" />
<input bindconfirm="handleConfirm" />Page({
data: {
count: 0,
user: {
name: '张三',
age: 20
},
list: [1, 2, 3]
},
// 更新简单数据
updateCount() {
this.setData({
count: this.data.count + 1
})
},
// 更新对象属性
updateUser() {
this.setData({
'user.name': '李四',
'user.age': 25
})
},
// 更新数组
updateList() {
this.setData({
'list[0]': 100, // 修改第一项
'list[3]': 4 // 添加新项
})
},
// 批量更新
batchUpdate() {
this.setData({
count: 10,
'user.name': '王五',
list: [10, 20, 30]
}, () => {
// 更新完成的回调
console.log('数据更新完成')
})
}
})// 1. 保留当前页面,跳转到新页面(可返回)
wx.navigateTo({
url: '/pages/detail/detail?id=123',
success() {
console.log('跳转成功')
}
})
// 2. 关闭当前页面,跳转到新页面(不可返回)
wx.redirectTo({
url: '/pages/home/home'
})
// 3. 跳转到 tabBar 页面
wx.switchTab({
url: '/pages/index/index'
})
// 4. 关闭所有页面,打开新页面
wx.reLaunch({
url: '/pages/index/index'
})
// 5. 返回上一页
wx.navigateBack({
delta: 1 // 返回的页面数,默认1
})// 页面A:传递参数
wx.navigateTo({
url: '/pages/detail/detail?id=123&name=test'
})
// 页面B:接收参数
Page({
onLoad(options) {
console.log(options.id) // 123
console.log(options.name) // test
}
})<view class="container">
<view class="counter">
<text class="title">计数器</text>
<view class="count">{{count}}</view>
<view class="buttons">
<button bindtap="decrease">-</button>
<button bindtap="reset">重置</button>
<button bindtap="increase">+</button>
</view>
</view>
</view>.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.counter {
background: white;
border-radius: 20rpx;
padding: 60rpx;
text-align: center;
box-shadow: 0 10rpx 40rpx rgba(0,0,0,0.1);
}
.title {
font-size: 40rpx;
font-weight: bold;
color: rgba(255, 255, 255, 0.85);
}
.count {
font-size: 120rpx;
font-weight: bold;
color: #667eea;
margin: 40rpx 0;
}
.buttons {
display: flex;
gap: 20rpx;
}
button {
flex: 1;
height: 80rpx;
line-height: 80rpx;
font-size: 32rpx;
}Page({
data: {
count: 0
},
increase() {
this.setData({
count: this.data.count + 1
})
},
decrease() {
this.setData({
count: this.data.count - 1
})
},
reset() {
this.setData({
count: 0
})
}
})