微信小程序教程
基于微信平台的接触即用应用;
- 兼有服务号的功能,同时提供类似原生的体验;(以前叫应用号)
- 适合做用完即走的应用,与用户的关系不是重依赖的关系;
体验官方示例,了解小程序组件;
- 组件:UI组件;
- 接口:动态API;
- 传统接口
- 微信开放接口
- 微信登录、获取用户信息、发起支付、分享、客服消息、模板消息。。。
思维上的借鉴,技术上不互通
知识背景:
- HTML CSS JavaScript
- Angular Vue React之类的MVVM框架
- 了解Node es6;
大纲:
- 基础
- UI
- api
- 实战
注册微信小程序账号
企业 & 个人
- 小程序、主体选个人;
- 绑定微信(后续可作为开发者);
- 获取小程序AppID
开发环境
安装微信开发者工具
- 工具使用微信扫码登录;
- 可以开发小程序和公众号;
- 填写AppID,及初始一个项目信息(非发布信息);
- 创建QuickStart项目(基于模板);或 选择一个已存在的项目目录;
- 编译运行查看;
开发工具介绍
基础设置:
- 设置-编辑项;去掉自动保存;
项目结构
- pages:各个页面
- utils:工具脚本
- app.js:应用程序逻辑
- app.json:应用程序配置
- app.wxss:应用程序公共样式
.js文件:
- 页面逻辑文件,用于创建页面对象,以及处理页面生命周期控制和数据处理
.wxml:
- 微信标记语言,用于定义页面中元素结构,语法遵循xml,注意不是html
.json:可选
- 设置当前额面工作是的window窗口配置,此处会覆盖app.json中的window设置,也就是说只可以设置window中的设置的属性;
.wxss:可选
- 微信样式表,用于定义页面样式,遵循css语法,扩展了css基本用法和长度单位(rpx 响应式像素);
小程序的配置
根目录下的app.json,以及每个页面下的json配置文件;
小程序框架的逻辑与界面分离的结构
逻辑:
- 由JavaScript完成处理生命周期事件,业务数据供给,界面事件处理;
页面:
- wxml wxss 展示逻辑层数据 接收用户输入;
小程序的生命周期
应用的:app.js
// 创建一个应用实例对象
App({
// 应用启动时触发
// 只会触发一次
obLaunch:function(){
console.log('1')
},
// 应用程序显示在屏幕上
// 从后台回来(多种回来的渠道)
onShow:function(options){
console.log('2')
},
//
onHide:function(){
console.log('3')
},
// 只能捕获运行时异常
onError:function(msg){
console.log('4')
},
// 在此添加的任意成员都是全局共享的
foo:'bar'
})
页面的:page.js
Page({
data:{
},
// 适合做页面的数据初始化
onLoad(){
// 获取全局唯一的实例对象
const app = getApp()
console.log(app.foo)
// this.data.foo = 'hw' 无效
this.setData({foo:'hello world!'})
},
// 页面进入到焦点状态
onShow(){
},
// 页面已准备好 数据渲染完成
onReady(){
// 设置导航标题
wx.setNavigationBarTitle({
title:'Wao!'
})
}
// 页面与页面之间的切换 导致的隐藏
obHide(){
}
// 页面导航栈 当前页面 退栈
onUnload(){
// 页面卸载前 保存页面状态 取消监听等
}
})
<navigator url="/pages/page1/page1">page1</navigator>
小程序的数据绑定
<view>
<!-- 绑定 -->
<text>{{name}}</text>
<!-- 补充拼接 -->
<input value="{{name}}BindingWord" />
<!-- 简单运算 -->
<text>{{name + 1}}</text>
<!-- 传布尔值 不用双括号将被判为字符串-->
<checkbox checked="{{false}}"></checkbox>
<!-- data装饰函数 -->
<text>{{foo.testFunc(name)}}</text>
</view>
<!-- 在视图层定义函数的方式 -->
<wxs module="foo">
<!-- 遵循commonjs规范 -->
<!-- 导出一个界面可使用的对象 -->
module.exports = {
testFunc: function(input){
return input + 1
}
}
</wxs>
Page({
// data中只能暴露数据成员 不可以是函数
data:{
// 视图层可访问属性
name:'haha',
}
})
控制属性——条件渲染
<view wx:if="{{isLoading}}">
<text>Loading...</text>
</view>
<!-- elif -->
<view wx:else>
<text>Loaded</text>
</view>
<!-- 频繁切换显示时 不建议用 wx:if , 而是使用hidden属性-->
<view hidden="{{!isLoading}}">
<text>Loading...</text>
</view>
<!-- 虚拟包裹标签 block:这是一个包装元素 不是一个实际的组件 不会影响页面结构 -->
<block>
<text></text>
</block>
Page({
data:{
isLoading:true
},
onReady(){
setTimeout(() => {
this.setData({isLoading:false})
},2000)
}
})
控制属性——列表渲染
<view>
<!-- 可以通过 *this 这个保留值 指定 当前被遍历的元素;指定key时用 wx:key="*this" -->
<view wx:for="{{students}}" wx:for-item="item" wx:for-index="index" wx:key="id">
<text>{{index}}</text>
<text>{{item.name}}</text>
</view>
</view>
<button bindtap="addItemHandler"></button>
Page({
data:{
students:[
{id:1, name:'1'},
{id:2, name:'2'},
]
},
// 事件处理函数
addItemHandler(event){
const students = this.data.students
// 在后边添加
students.push({id:3, name:'3'})
// 在前边添加(如果不设置key 就会出现问题)
students = [{id:3, name:'3'}].concat(this.data.students)
this.setData({students})
}
})
事件处理
事件冒泡:
- 子视图的bindtap会被冒泡到父视图的bindtap;
- 可以使用catchtap来取消事件冒泡;
注: ctrl + D 批量编辑
对于多个button添加相同处理函数区分额外的传入参数方式:
- 对标签添加自定义属性 如 data-id=‘1’;
- 事件参数event.target.dataset.id
单向数据流
Page({
data:{
foo:"hello world"
},
inputChangeHandler(e){
//当前文本框 修改之后的值
let foo = e.detail.value
// 和react类似 单向数据流
this.setData({foo})
}
})
<text>{{foo}}</text>
<input value="{{foo}}" bindinput="inputChangeHandler"/>
WXSS vx CSS
样式导入:
@import "../xxx/xxx.wxss";
,多页面间共享样式、第三方UI组件库 如WeUI-wxss;
拓展尺寸单位:rpx
- 规定屏幕宽度为750rpx;
注:gulp工作流
注:小程序能访问的第三方域名,需要在小程序的开发者后台进行配置;
注:小程序对上传程序包大小限制为1M;
对服务端发送请求
网络接口:wx.request(obj)
wx.request({
url:'',// 没有跨域的概念 但需要在后台添加需要请求的其他域(https,需备案)
header:{
'Content-Type':'application/json'
// ...
}
success:function(res){
console.log(res)
}
})
一般会提取到一个公共的js文件中 进行二次封装:遵循 commonjs 规范
// commonjs 规范
module.exports = (url,data) => {
return new Promise((resole,reject) => {
wx.request({
url:`https://common/${url}`,// 没有跨域的概念 但需要在后台添加需要请求的其他域(https,需备案)
header:{
'Content-Type':'application/json'
// ...
}
success:resole,
fail:reject
})
})
}
const fetch = require('../../utils/fetch')
Page({
onLoad:function(options){
fetch('urlsub').then(res => {
//
})
}
})
页面间跳转及传参
跳转api:
- wx.openTab
?
navigator组件:
<navigator url="/pages/message/message?cat={{operationID}}">
<!-- 对tabVC切换无效 只适合栈式切换 tabVC切换 要使用 wx.switchTab -->
</navigator>
Page({
onLoad(options){
// 即传入的{cat:1}
}
})
列表页展示及上拉加载和下来刷新
<view wx:if="{{hasMore}}" class="loadmore loading">正在加载...</view>
<view wx:else class="loadmire">没有更多了</view>
const fetch = require('../../utils/fetch')
Page({
onLoad:function(options){
fetch(`urlsub/${id}`).then(res => {
// onReady时 才可以进行UI相关设置 这里设置title可能会有问题:有可能设置不成功
// 可以先设置到数据data中 在inReady时再进行设置
wx.setNavigationBarTitle({
title:'res.data.title'
})
return fetch(`urlsublist/${id}`,{page:1,limit:10})
}).then(res => {
// 第一个then返回的Promise对象
})
},
onReachBottom:function(){
// 需要判断是否正在加载中 否则会有多次触发的问题
},
onPullDownRefresh:function(){
// 网络请求的方法若回调成功 可以返回一个Promise 然后在then中执行如下方法
wx.stopPullDownRefresh()
},
onShareAppMessage:function(){
}
})
图片预览
wx.previewImage()
<!-- 标签元素 处理函数 传参的方式 -->
<image src="{{item}}" mode="aspectFill" bindtap="previewHandler" data-src="{{item}}" />
小结:
该文为视频学习笔记,旨在了解小程序的开发流程,学习了基础的页面开发的若干节点,语法与Vue大同小异;
参考微信小程序开发文档 再走一遍,能熟练使用即可。