一、导入小程序
-
选择代码目录
-
项目配置文件
appid
当前小程序的 AppIDprojectname
当前小程序的项目名称
-
变更AppID(视情况而定,如果没有开发权限时需要变更成个人的 AppID)
二、模板语法
在页面中渲染数据时所用到的一系列语法叫做模板语法,对应到 Vue 中就是指令的概念。
2.1 数据绑定
-
插值
{{}}
小程序中使用
{{}}
实现数据与模板的绑定,与 Vue 中不同的是无论是属性的绑定还是内容的绑定都必须要使用{{}}
。<!-- 此处的 false 是字符串的 'false',因此布尔结果为 true --> <switch checked="false" /> <!-- 如下才是正确表示布尔值 false 的方法 --> <switch checked="{{false}}" />
-
简易数据绑定
小程序中提供了
model:value="{{数据名}}"
语法来实现双向的数据绑定,但是目前只能用在input
和textarea
组件中。
本节中用到的演示代码如下:
<!-- 数据绑定 -->
<view class="binding">
<!-- 开关组件 -->
<switch checked="{{ isOpen }}"/>
<!-- 双向数据绑定 -->
<input type="text" model:value="{{ message }}" />
<view class="message">{{ message }}</view>
</view>
Page({
data: {
isOpen: true,
message: 'hello world!'
}
})
2.2 条件渲染
- 控制属性:相当于 Vue 中指令的概念,在小程序中做控制属性
wx:if
根据表达式的值渲染内容,值为真时显示wx:else
用在wx:else
的后面,不可单独使用,wx:if
表达式值为假时显示
- 组件属性:
- hidden 根据表达式的值渲染内容,值为真时隐藏
- 通过
[hidden] { display: none; }
来实现内容的隐藏
本节中用到的演示代码如下:
<!-- 条件渲染 wx:if 和 wx:else -->
<view class="welcome">
<text wx:if="{{ isLogin }}">大师兄</text>
<text wx:else>游客</text>你好:
</view>
<!-- 条件渲染 hidden -->
<view class="loading">
<!-- 可以单独使用 -->
<!-- <text wx:if="{{ !loaded }}">正在加载...</text> -->
<text hidden="{{ loaded }}">正在加载...</text>
</view>
Page({
data: {
isOpen: true,
message: 'hello world!',
isLogin: true,
loaded: false
}
})
2.3 列表渲染
wx:for
根据数组重复渲染组件内容index
默认值,访问数组的索引值item
默认值,访问数组的单元值
wx:key
列表项的唯一标识符(不使用 {{}})- 数组单元是对象时,只需要写属性名
- 数组单元是简单类型时,推荐使用
*this
wx:for-index
自定义访问数组索引的变量名wx:for-item
自定义访问数组单元的变量名
本节中用到的演示代码如下:
<!-- 列表渲染 -->
<view class="students">
<view class="item">
<text>序号</text>
<text>姓名</text>
<text>年龄</text>
<text>性别</text>
<text>级别</text>
</view>
<view class="item">
<text>1</text>
<text>贺洋</text>
<text>20</text>
<text>男</text>
<text>菜鸟</text>
</view>
</view>
<!-- 简单数组 -->
<view class="history">
<text>小米</text>
</view>
Page({
data: {
isOpen: true,
message: 'hello world!',
isLogin: true,
loaded: false,
students: [
{id: 1, name: '贺洋', age: 20, gender: '男', level: '菜鸟'},
{id: 2, name: '唐刚', age: 18, gender: '女', level: '笨鸟'},
{id: 3, name: '常超', age: 20, gender: '女', level: '老鸟'}
],
history: ['苹果', '华为', 'OPPO', '三星']
}
})
三、内置API
内置 API 实际上就是小程序提供的一系列的方法,这些方法都封装在了全局对象 wx
下,调用这些方法实现小程序提供的各种功能,如网络请求、本地存储、拍照、录音等。
3.1 网络请求
调用 wx.request
能够在小程序中发起网络请求与后端接口进行数据的交互,其语法格式如下:
wx.request({
url: '这里是接口的地址',
method: '这里是请求的方法',
data: '请求时提交的数据',
header: {/* 请求头信息 */},
success: () => {/* 成功的回调 */},
fail: () => {/* 失败的回调 */},
complete: () => {/* 成功或失败的回调 */}
})
本节中用到的演示代码如下:
<button class="button" size="mini" type="primary">查询书单</button>
<view class="books">
<view class="item">
<text>序号</text>
<text>名称</text>
<text>作者</text>
<text>出版社</text>
<text>操作</text>
</view>
<view class="item">
<text>1</text>
<text>西游记</text>
<text>吴承恩</text>
<text>人民文学出版社</text>
<text>删除</text>
</view>
</view>
Page({
data: {
books: []
},
// 调用数据接口的方法
getBooks() {
// 调用小程序的 API 发起请求
wx.request({
url: 'https://hmajax.itheima.net/api/books',
method: 'GET',
data: {
creator: 'zhangsan'
},
success: (result) => {
// 更新数据,渲染页面
this.setData({ books: result.data.data })
}
})
}
})
3.2 界面交互
-
wx.showLoading
显示 loading 提示框-
title
文字提示内容 -
mask
是否显示透明蒙层,防止触摸穿透
-
-
wx.hideLoading
隐藏 loading 提示框 -
wx.showToast
消息提示框(轻提示)mask
是否显示透明蒙层,防止触摸穿透duration
延迟时间(提示框显示多久)icon
指定图标,none
不使用图标
3.3 本地存储
wx.setStorageSync
存入一个数据,复杂类型数据不需要JSON.stringify
处理wx.getStorageSync
读取一个数据,复杂类型数据不需要JSON.parse
处理wx.removeStorageSync
删除一个数据wx.clearStorageSync
清空全部数据
本节中用到的演示代码如下:
<!-- 本地存储 -->
<view class="storage">
<button size="mini" type="primary">存数据</button>
<button size="mini" type="primary">读数据</button>
<button size="mini" type="primary">删数据</button>
<button size="mini" type="primary">清数据</button>
</view>
3.4 API 特征
小程序中提供的 API 数量相当的庞大,很难也没有必要将所有的 API 全部掌握,但是这些 API 具有一些共有的特征:
- 异步 API:绝大部分的 API 都是异步方式,通过回调函数获取 API 执行的结果
success
API 调用成功时执行的回调fail
API 调用失败时执行的回调complete
API 调用结束时执行的回调(无论成功或失败)
- 同步 API:部分 API 支持以同步方式获取结果,这些 API 的名称都以
Sync
结尾,如wx.getStorageSync
等 - Promise:部分异步的 API 也支持以 Promise 方式返回结果,此时可以配合
asyc/await
来使用
3.5 相册/拍照
wx.chooseMedia
调起摄像头拍照或读取相册内容,该 API 既支持回调方式获取结果,也支持 Promise 方式返回结果:
<view class="preview" bind:tap="onChoose">
<image src="{{ avatar }}" mode="aspectFill" />
</view>
Page({
// 用于页面渲染的数据
data: {
avatar: ''
},
// 选择图片
async onChoose() {
// 推荐使用 async await 的写法,减少不必要的回调地狱
const res = await wx.chooseMedia({
mediaType: ['image'],
count: 1
})
this.setData({
avatar: res.tempFiles[0].tempFilePath
})
}
})
3.6 小练习
本节搜索历史练习用到的演示代码如下:
<!-- 搜索历史 -->
<view class="history">
<view class="search-bar">
<input type="text" />
<text class="label">搜索</text>
</view>
<view class="title">
历史搜索 <text class="icon-delete">x</text>
</view>
<view class="keywords">
<navigator url="/pages/test/index">小米</navigator>
<navigator url="/pages/test/index">苹果</navigator>
<navigator url="/pages/test/index">华为</navigator>
</view>
</view>
四、事件处理
4.1 事件对象
前面已经介绍过小程序事件监听的语法:bind:事件类型=事件回调
,但是小程序的事件回调不支持传参数,因此要将模板中的数据传递到事件回调中就必须要通过事件对象来实现。
小程序事件回调函数的第1个参数即为事件对象,事件对象中包括了一些有用的信息:
Page({
eventHandler(ev) {
// 查看事件对象
console.log(ev)
}
})
本节练习用到的演示代码如下:
<!-- 搜索框 -->
<view class="search-bar">
<input type="text" placeholder="输入搜索关键字" />
</view>
<!-- 页面主体 -->
<view class="page-body">
<scroll-view scroll-y class="aside">
<view wx:for="{{6}}" wx:key="*this" class="item"></view>
</scroll-view>
<scroll-view scroll-y refresher-enabled class="content">
<view wx:for="{{6}}" wx:key="*this" class="item"></view>
</scroll-view>
</view>
4.2 组件事件
前面介绍的 tap
事件可以在绝大部分组件是监听,我们可以将其理解为通用事件类型,然而也有事件类型只属于某个组件,我们将其称为组件事件。
scroll-view
组件中的事件:
bind:scrolltolower
当滚动内容到达底部或最右侧时触发bind:refresherrefresh
执行下拉操作时触发refresher-enable
启用自定义下拉刷新
本节练习用到的演示代码如下:
Page({
data: {
isPulling: false
},
onScrollPulling() {
// 请求最新的数据
wx.request({
url: 'https://hmajax.itheima.net/api/books',
data: {creator: 'zhangsan'},
success: (result) => {},
complete: () => {
// 停止下拉刷新
this.setData({isPulling: false})
}
})
}
})
表单组件中的事件:
change
表单数据发生改变时触发(input 不支持)submit
表单提交时触发,button
按钮必须指定form-type
属性
本节练习用到的演示代码如下:
<!-- 用户信息 -->
<view class="register">
<form>
<view class="form-field">
<label for="">姓名:</label>
<view class="field">
<input type="text" placeholder="请输入您的姓名" />
</view>
</view>
<view class="form-field">
<label for="">性别:</label>
<view class="field">
<radio-group>
<radio value="男" checked />男
<radio value="女" />女
</radio-group>
</view>
</view>
<view class="form-field">
<label for="">爱好:</label>
<view class="field">
<checkbox-group>
<checkbox value="写代码" checked />写代码
<checkbox value="睡大觉" />睡大觉
</checkbox-group>
</view>
</view>
<view class="form-field">
<label for="">籍贯:</label>
<view class="field">
<picker mode="region">请选择籍贯</picker>
</view>
</view>
<button size="mini" type="primary">保存</button>
</form>
</view>
五、生命周期
生命周期是一些名称固定自动执行的函数。
5.1 页面生命周期
onLoad
在页面加载完成时执行,只会执行 1 次,常用于获取地址参数和网络请求onShow
在页面处于可见状态时执行,常用于动态更新数据或状态onReady
在页面初次渲染完成时执行,只会执行 1 次,常用于节点操作或动画交互等场景onHide
在页面处于不见状态时执行,常用于销毁长时间运行的任务,如定时器
本节练习用到的演示代码如下:
<view class="history">
<view class="title">历史搜索</view>
<view class="keywords">
<navigator
wx:for="{{history}}"
wx:key="*this"
url="/pages/test/index">
{{item}}
</navigator>
</view>
</view>
<view class="form-field">
<input type="text" placeholder="请输入手机号" />
<text
wx:if="{{time === 0}}"
bind:tap="getSMSCode"
class="label"
>获取短信验证码</text>
<text wx:else class="label">{{time}}后重新获取</text>
</view>
// 定时器ID
let timer = null
Page({
data: {
history: [],
time: 0
},
getSMSCode() {
let time = 60 // 初始数据
// 倒计时
timer = setInterval(() => {
// 停止定时器
if(--time < 0) return clearInterval(timer)
this.setData({time}) // 渲染结果
}, 1000)
},
})
5.2 应用生命周期
onLaunch
小程序启动时执行1次,常用于获取场景值或者启动时的一些参数(如自定义分享)onShow
小程序前台运行时执行,常用于更新数据或状态onHide
小程序后台运行时执地,常用于销毁长时间运行的任务,如定时器
本节练习用到的演示代码如下:
// pages/lifetimes/index.js
Page({
// 小程序转发/分享
onShareAppMessage() {
return {
title: '小程序学习',
path: '/pages/index/index?test=测试数据',
imageUrl: '/static/images/cover.png'
}
}
})