快速上手
在本章节中,我们将介绍如何快速上手微信小程序开发。
精简项目
首先,我们将无关紧要的文件删除,只保留必要的文件。
如下图所示
├── app.js
├── app.json
├── app.wxss
└── pages
└── index
├── index.js
├── index.json
├── index.wxml
└── index.wxss{
"entryPagePath": "pages/index/index",
"pages": ["pages/index/index"],
"window": {
"navigationBarTitleText": "微信小程序演示", # 页面名字
"navigationBarBackgroundColor": "#0000ff", # 顶部颜色
"enablePullDownRefresh": true, # 是否支持下拉刷新
"backgroundColor": "#eaeaea", # 背景颜色
"backgroundTextStyle": "light" # 背景文字颜色
},
"style": "v2",
"componentFramework": "glass-easel",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents"
}// app.js
App({});{
"usingComponents": {},
"navigationBarTitleText": "首页", # 页面名字
"navigationBarBackgroundColor": "#000000", # 顶部颜色
"enablePullDownRefresh": true, # 是否支持下拉刷新
"backgroundTextStyle": "light" # 背景文字颜色
}Page({
//
});<!--index.wxml-->
<view>
<text>Hello World</text>
</view>tabbar 配置
tabbar 用于底部或顶部的 tab 导航页。
在项目根目录下的全局配置文件 app.json 中配置 tabbar。
{
"entryPagePath": "pages/index/index",
"pages": [
"pages/index/index",
"pages/my/my"
],
// ...
"tabBar": {
"selectedColor": "#000000",
"position": "bottom",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "/images/tabbar/home.png",
"selectedIconPath": "/images/tabbar/home-selected.png"
},
{
"pagePath": "pages/my/my",
"text": "个人中心",
"iconPath": "/images/tabbar/my.png",
"selectedIconPath": "/images/tabbar/my-selected.png"
}
]
}
}并将图片 home.png、home-selected.png、my.png、my-selected.png 放入项目根目录下的 images/tabbar 目录下。
温馨提示
pages/my/my 页面在 app.json中配置后会自动生成。
常用组件
对比 html 中的标签,包括:div、a、span、img等,小程序中对应的叫做组件。
比如对应关系:
div对应小程序中的view组件a对应小程序中的navigator组件span对应小程序中的text组件img对应小程序中的image组件
view 组件
小程序中的 view 组件用于创建一个块级元素,用于包裹其他组件。
<view>
<text>Hello World</text>
</view>官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/view.html
text 组件
小程序中的 text 组件用于创建一个文本元素,用于显示文本内容。
<text>Hello World</text>官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/text.html
button 组件
小程序官方按钮组件 button 提供了一下预设的样式。
type可以取值default、primary、warn、minisize可以取值default、miniplain表示是否为镂空按钮
<button size="mini" type="default">按钮文本</button>
<button size="mini" type="warn">按钮文本</button>
<button size="mini" type="primary" plain>按钮文本</button>温馨提示
在小程序开发中,取值为 true 或 false的属性,如果取值为 true 时一般只需要写属性名即可,不需要写属性值。
比如 <button plain></button> 而不建议写成 <button plain="true"></button>,因为它们的效果是一样的。
官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/button.html
navigator 组件
小程序中的 navigator 组件用于创建一个链接,用于跳转到其他页面。
<navigator open-type="navigate" url="/pages/my/my">
<text>跳转到个人中心</text>
</navigator>open-type 可以取值 navigate、redirect、switchTab、reLaunch、navigateBack。
navigate表示跳转到普通页面,不能跳转到 tabbar 页面redirect表示跳转到普通页面并关闭当前页面,不能跳转到 tabbar 页面switchTab表示跳转到tabbar页面,并关闭其他非 tabbar 页面reLaunch表示重新启动应用并跳转到普通页面navigateBack关闭当前页面,并返回上一页或多级页
官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html
image 组件
小程序中的 image 组件用于创建一个图片元素,用于显示图片内容。
<image src="/images/avatar.png"></image>icon 组件
<icon type="success" color="blue" size="64" />type 可以取下面的列表值:success, success_no_circle, info, warn, waiting, cancel, download, search, clear。
官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/icon.html
swiper 组件
swiper 组件用于创建一个轮播图,它的字组件必须是 swiper-item 组件。
常使用的属性包括:
autoplay属性表示是否自动播放indicator-dots属性表示是否显示指示点circular属性表示是否循环播放interval属性表示自动播放的间隔时间
swiper-item 组件用于创建轮播图中的每一项。
<swiper autoplay indicator-dots circular interval="3000">
<swiper-item>1</swiper-item>
<swiper-item>2</swiper-item>
<swiper-item>3</swiper-item>
</swiper>温馨提示
当 swiper-item 组件中包裹的是 image 组件,如果需要将图片在宽度上铺满,建议将 image 组件的 width 属性设置为 750rpx,mode 设置为 widthFix。
<swiper
autoplay
indicator-dots
indicator-color="white"
indicator-active-color="gray"
circular
interval="3000"
>
<swiper-item>
<image
style="width: 750rpx;"
mode="widthFix"
src="/images/banner/banner1.jpeg"
/>
</swiper-item>
<swiper-item>
<image
style="width: 750rpx;"
mode="widthFix"
src="/images/banner/banner2.jpeg"
/>
</swiper-item>
<swiper-item>
<image
style="width: 750rpx"
mode="widthFix"
src="/images/banner/banner3.jpeg"
/>
</swiper-item>
</swiper>官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html
尺寸单位 rpx
在 web 开发中,尺寸单位一般采用 px 像素值,在小程序开发中,一般采用 rpx 单位,rpx 单位是相对于屏幕宽度的比例单位。
<view style="width: 750rpx; height: 300rpx; background-color: azure;"></view>注意
宽度 750rpx 则占据屏幕宽度的 100%。
样式
微信小程序中包含全局样式 app.wxss 、局部页面样式 page.wxss和局部组件样式 component.wxss。
注意
样式一般写在 wxss 文件中,一般不直接写在 style 中。
全局样式
全局样式 app.wxss 定义了全局的样式,所有页面都生效。
/* 使用类选择器选择组件 */
.container {
width: 750rpx;
height: 350rpx;
background-color: azure;
}<view class="container"></view>局部页面样式
局部页面样式 page.wxss 定义了当前页面的样式,只在当前页面生效。
事件绑定
在小程序开发中,经常遇到需要绑定事件的情况,比如点击事件、输入事件、触摸事件等。
点击事件
基本使用
点击事件 bind:tap 用于绑定点击事件,当用户点击组件时触发。
<!--pages/index/index.wxml-->
<button bind:tap="handleClick">点击我</button>// pages/index/index.js
Page({
handleClick() {
console.log("点击了组件");
},
});bind:tap可以在任何组件上使用,比如view、button、text等。bind:tap事件绑定也可以简写成bindtap。
注意
在小程序开发中,事件绑定的函数必须在 Page 实例中定义。
事件冒泡
事件冒泡是指事件从子元素向父元素传递的过程。
<view
bind:tap="handleParent"
style="height: 400rpx; width: 750rpx; background-color: floralwhite; display: flex; align-items: center;"
>
<button bind:tap="handleChild" type="primary" plain>事件冒泡</button>
</view>// pages/my/my.js
Page({
handleParent() {
console.log("Parent clicked!");
},
handleChild() {
console.log("Child clicked!");
},
});上述案例中,点击按钮 事件冒泡 会先触发 handleChild 函数,然后触发 handleParent 函数。
要阻止事件冒泡可以使用 catch:tap 绑定事件,catch 会阻止事件向上冒泡。
<view
bind:tap="handleParent"
style="height: 400rpx; width: 750rpx; background-color: floralwhite; display: flex; align-items: center;"
>
<button catch:tap="handleChild" type="primary" plain>事件冒泡</button>
</view>事件传参数
小程序中事件传参数的方式有两种:
通过
data-*传递参数html<button bind:tap="handleClick" data-type="breakfast" data-id="123"> 点击我 </button>jsPage({ handleClick(e) { const { id, type } = e.currentTarget.dataset; console.log(id, type); // 123 breakfast }, });通过
mark:*传递参数html<button bind:tap="handleClick" mark:type="breakfast" mark:id="123"> 点击我 </button>jsPage({ handleClick(e) { const { id, type } = e.mark; console.log(id, type); // 123 breakfast }, });注意
mark和dataset很相似,主要区别在于:mark会包含从触发事件的节点到根节点上所有的mark:属性值;而dataset仅包含一个节点的data-属性值。
页面跳转
在小程序开发中,经常需要实现页面跳转的功能,比如点击按钮跳转到详情页、点击列表项跳转到详情页等。
声明式跳转
声明式跳转是指在 wxml 文件中使用 navigator 组件实现跳转。
基础方式
html<navigator url="/pages/login/login">登录</navigator>跳转时携带参数
html<navigator url="/pages/login/login?name=example">登录</navigator>js// pages/login/login.js Page({ onLoad(options) { const { name } = options; console.log(name); // example }, });
编程式跳转
编程式跳转是指在 js 文件中使用 wx.navigateTo 方法实现跳转。
// pages/index/index.js
Page({
handleNavigateTo() {
wx.navigateTo({ url: "/pages/login/login" });
},
handleRedirectTo() {
wx.redirectTo({ url: "/pages/login/login" });
},
handleSwitchTab() {
wx.switchTab({ url: "/pages/index/index" });
},
handleReLaunch() {
wx.reLaunch({ url: "/pages/login/login" });
},
handleNavigateBack() {
wx.navigateBack({ delta: 1 });
},
});模版语法
小程序中的模版语法和 Vue 中的模版语法基本一致。
在 wxml 文件中使用 2 个大括号包裹变量,在 js 文件中的 data 中定义变量。
<view><text>Name:{{ name }}</text></view>
<view><text>Age:{{ age }}</text></view>Page({
data: {
name: "Steven",
age: 18,
},
});也可以渲染对象。
<view><text>Name:{{ user.name }}</text></view>
<view><text>Address: {{ user.address.city }}</text></view>
<view><text>Hobbies: {{ hobbies }}</text></view>
<view><text>Address: {{ user.address.street }}</text></view>Page({
data: {
user: {
name: "Steven",
hobbies: ["reading", "traveling"],
address: {
city: "Shanghai",
street: "Nanjing Road",
},
},
},
});进行简单的算数运算和逻辑运算
<view><text>{{ 99 + 1 }}</text></view>
<view><text>{{ 99 >= 1 }}</text></view>使用三元运算。
<view>
<text> {{ age >= 18 ? "成年人" : "未成年人" }} </text>
</view>Page({
data: {
age: 18,
},
});响应式数据
小程序中的数据是响应式的,当数据发生变化时,会自动更新视图。
在 js 中使用 this.setData({key: 变化后的值}) 方法更新数据。
下面以经典的修改数字增加的例子作为演示:
<view>
<button bind:tap="handleCounter" type="primary" plain>增加</button>
<text>当前计数:{{ counter }}</text>
</view>Page({
data: {
counter: 0,
},
handleCounter() {
this.setData({
counter: this.data.counter + 1,
});
},
});修改对象元素。
// pages/my/my.js
Page({
data: {
user: {
hobby: "reading",
},
},
handleChangeHobby() {
// 方式一:常规方式修改对象
// this.setData({
// "user.hobby": "travling"
// })
// 方式二:解构赋值
const user = { ...this.data.user, hobby: "travling" };
// const user = Object.assign(this.data.user, {hobby: "travling"});
this.setData({
user,
});
},
});<button bind:tap="handleChangeHobby">Change Hobby</button>
<text>{{ user.hobby }}</text>循环 wx:for
小程序中使用 wx:for 循环渲染数组列表,并使用 wx:key 绑定列表项的唯一标识。
其中 index 和 item 分别表示当前项的索引和当前项的值。
<view>
<button bind:tap="handleAddAnimal">Add animal</button>
<text wx:for="{{ animals }}" wx:key="index">{{ item }}</text>
</view>Page({
data: {
animals: ["Dog", "Cat", "Elephant"],
},
handleAddAnimal() {
// 方式一:先追加,再设置
this.data.animals.push("Pig");
this.setData({
animals: this.data.animals,
});
// 方式二:contact
const animals = this.data.animals.concat("Pig");
this.setData({
animals,
});
// 方式三:解构赋值
const animals = [...this.data.animals, "Pig"];
this.setData({
animals,
});
},
});条件渲染 wx:if
小程序中使用 wx:if、wx:elif 和 wx:else 进行条件渲染。
<view>
<text wx:if="{{ score >= 80 }}">A++</text>
<text wx:elif="{{ score >= 60 && score < 80 }}">A+</text>
<text wx:else>A</text>
</view>Page({
data: {
score: 78,
},
});小程序中有另外一个指令 hidden ,和 wx:if 指令的功能类似,但是 hidden 指令会将元素渲染到页面中,只是通过 CSS 样式将元素隐藏起来。
<view>
<button bind:tap="toggleText">Toggle</button>
<text hidden="{{ textActive }}">Hello world</text>
</view>Page({
data: {
textActive: true,
},
toggleText() {
this.setData({
textActive: !this.data.textActive,
});
},
});网络请求 wx:request
小程序中使用 wx:request 进行网络请求。
使用wx:request时的对象参数包括:
url为请求的地址method为请求的方法,比如常见的GET、POSTdata为请求的参数,GET请求时会将参数拼接在 URL 中,POST请求时会将参数放在请求体中header为请求的头信息,比如Accept、Content-Type等success为请求成功的回调函数,参数为请求成功的响应数据fail为请求失败的回调函数,参数为请求失败的错误信息complete为请求完成的回调函数,无论请求成功还是失败都会调用,参数为请求的配置对象
Page({
handleRequest() {
wx.request({
url: "https://www.baidu.com",
method: "GET",
data: {},
header: {},
success: (res) => {
console.log(res);
},
fail: (error) => {},
complete: () => {},
});
},
});<view>
<button bind:tap="handleRequest">Request</button>
</view>wx:showLoading 加载提示框
小程序中使用 wx:showLoading 显示加载提示框。
Page({
handleRequest() {
wx.showLoading({
title: "数据加载中",
mask: true,
});
wx.request({
url: "https://www.baidu.com",
method: "GET",
data: {},
header: {},
success: (res) => {
console.log(res);
},
fail: (error) => {},
complete: () => {
wx.hideLoading();
},
});
},
});<view>
<button bind:tap="handleRequest">Request</button>
</view>