微信小程序开发(1)
微信小程序开发(1)
代码结构与基本配置
代码结构与基本配置
- App.js 注册一个微信小程序
- App.json 小程序全局配置(网络请求的超时时间、窗口表现、各个页面的注册路径
- App.wxss 小程序全局样式
- Project.config.json 保存微信开发者工具的配置信息,重新安装工具时可用
- Pages 所有页面,每个页面最多由四个文件组成:
- js:处理页面逻辑和一些数据交互
- json:页面配置信息
- wxml:展示页面元素和内容
- wxss:设置页面元素样式
- Utils
Util.js 存放工具函数(达到代码复用的目的)
基本HelloWorld创建
App.js:注册小程序的应用,调用App()函数,传入Object类型参数 App({})
App.json:注册小程序所有页面的路径,通过pages属性,值为list类型,list中是所有页面的路径
{ "pages": [ ] }
Helloworld.wxml:描述页面的内容,view标签。
Helloworld Helloworld.js:注册小程序页面,类似于app.js,通过page()函数,传入object类型参数(页面的生命周期钩子、时间处理函数、页面的默认数据等等)
Page({})
Helloworld.json:helloworld的页面一些配置
{}
Helloworld.wxss:描述小程序页面的样式
开发框架——基本构成
微信开发者工具
版本控制
- console:打印小程序页面调试log信息
- sources:所有脚本文件,可进行断点调试
- network:展示各个网络请求的状态信息、所请求资源的响应数据
WXML
wxml语法
wxml(weixin markup language)是框架设计的一套标签语言,结合组件、 wxs和时间系统,可以构建处页面的结构。
语法
<标签名 属性名="属性名1" 属性名="属性名2" …>
//属性值大小写敏感 …
</标签名>
案例
<!-- index.wxml -->
<view class="classname" data-name="A">
Hello woeld!
<view>
Hello China!
</view>
</view>
注意:
① view标签必须严格闭合
② 属性值大小写敏感
wxml特性
四个主要特性:数据绑定、列表渲染、条件渲染、模板引用
数据绑定
实现对数据的实时更新,使我们拥有动态改变页面的能力
案例
1.文本内容绑定
<!--index.wxml-->
<view>
<text>{{message}}</text>
</view>
{{Mustache}} 绑定语法,把变量包起来
//index.js
Page({
data:{
message:"Hello world"
}
})
2.属性绑定
<!--index.wxml-->
<view>
<text data-name="{{theName}}">
</text>
</view>
注意:所有的组件和属性都必须是小写
//index.js
Page({
data:{
theName:"Jack"
}
})
页面渲染结果:
3.运算符绑定
<!--index.wxml-->
<view hidden="{{flag ? true : false}}">
Hidden
</view>
hidden属性:值为 true 时隐藏 view 标签内容
//index.js
Page({
data:{
flag: false
}
})
view 标签属性
属性名 | 类型 | 描述 | 注解 |
---|---|---|---|
id | String | 组件的唯一标示 | 保持整个页面唯一 |
class | String | 组件的样式类 | 在对应的 wxss 中定义的样式类,静态设置属性 |
style | String | 组件的内联样式 | 可以动态设置的内联样式 |
hidden | Boolean | 组件是否隐藏 | 默认值 false ,所有组件默认显示 |
data-* | Any | 自定义属性 | 组件上触发的事件时,会发送给事件处理函数 |
bind* / catch* | EventHandler | 组件的事件 |
列表渲染
案例
<!--index.wxml-->
<view>
<block wx:for="{{items}}" wx:for-item="item" wx:key="index">
<view>{{index}}:{{item.name}}</view>
</block>
</view>
- 用 wx:for 绑定数组,从而使用列表渲染特性;
- index 变量:当前元素在数组中的下标
- item 变量:当前元素
- wx:key 列表中的唯一标识符,若是静态列表,或不需要维护列表状态,可忽略该属性
- block 标签:不是组件,而是包装元素,在页面渲染时不会被渲染
//index.js
Page({
data:{
items:[
{name:"商品A"},
{name:"商品B"},
{name:"商品C"},
{name:"商品D"},
{name:"商品A"}
]
}
})
条件渲染
案例
<!--index.wxml-->
<view>今天吃什么?</view>
<view wx:if="{{condition === 1}}">
饺子
</view>
<view wx:elif="{{condition === 2}}">
米饭
</view>
<view wx:else>
面食
</view>
- condition 传入 1-3 随机整数
- hidden 始终渲染,wx:if 在切换代码块时局部渲染;相比之下,hidden 有更高的初始化渲染消耗,wx:if 有更高的切换消耗,因此,当元素需要频繁切换显示时,使用 hidden 属性更好。
//index.js
Page({
data:{
condition: Math.floor(Math.random()*3+1)
}
})
模板及引用
在模板中自定义代码片段,在不同的地方调用或引用
案例
1.模板引用
<!--index.wxml-->
<template name="tempItem">
<view>
<view>收件人:{{name}}</view>
<view>联系方式:{{phone}}</view>
<view>地址:{{address}}</view>
</view>
</template>
<template is="template" data="{{...item}}"></template>
- is 属性:进行动态绑定模板
- data 属性:向模板中传入数据信息,模板拥有自己的作用域,只能通过 data 属性传值
//index.js
Page({
data:{
item:{
name:"张三",
phone:"11122223333",
address:"中国"
}
}
})
2.文件引用
import
- import 只能引用模板文件中的模板内容块
<!--index.wxml-->
<import src="a.wxml"></import>
<template is="a"></template>
- src 属性:声明模板文件路径
- is 属性:声明所引用的模板名
<!--a.wxml-->
<view>Hello world</view>
<template name="a">
Hello,World!
</template>
- import 作用域:只能引用目标文件中定义的 template 模板,如果目标文件中还嵌套了其他文件的 template 模板,那么其他文件中的模板就不会被引用
<!--index.wxml-->
<import src="a.wxml"></import>
<template is="a"></template>
<!--a.wxml-->
<import src="b.wxml"></import>
<template name="a">
This is a.wxml
</template>
<template is="b"></template>
<!--b.wxml-->
<template name="b">
This is b.wxml
</template>
include
include 是把目标文件内除了模板代码块之外的所有代码都引入,相当于将代码拷贝到了 include 的位置
<!--index.wxml-->
<include src="a.wxml"></include>
<template is="a"></template>
<!--a.wxml-->
<template name="a">
<view>
This is a.wxml
</view>
</template>
<view>Hello,world</view>
运行之后可以发现,并没有将 a.wxml 文件中的 a 模板渲染出来。
WXSS
WXSS(WeiXin Style Sheets) 是一套样式语言,用于描述 WXML 的组件样式,与 Web 开发中的 CSS(Cascading Style Sheets) 极为相似,为了适合小程序的开发, wxss 对 css 做了一定的修改和补充。
- 尺寸单位 rpx
- 样式导入
- 内联样式
- 选择器
wxss特性
响应式像素
-
设备像素(device pixels):设备屏幕的像素点,即屏幕分辨率
-
css 像素(css pixels):css样式代码中所使用的逻辑像素
-
PPI/DPI(pixel per inch):每英寸的像素数,数值越大,表示显示屏能以越高的密度显示图像,计算公式如下:
以 iPhone6 为例:
iPhone6 的屏幕尺寸为 4.7 英寸,计算得出 PPI=325.6,约等于官方值 326 。
-
DPR(device pixel Ratio):指手机在某一方向上的设备像素与 css 像素之比
-
rpx :微信团队规定手机屏幕宽度为 750rpx ,从而可以根据屏幕宽度实现自适应
样式
案例
外联样式导入
<!--index.wxml-->
<view class="container">
Hello,world!
</view>
/** index.wxss **/
@import './assets.wxss';
.container {
color: red;
}
/** assets.wxss **/
.container {
border: 1px solid #000;
}
注意:样式文件执行顺序为”从上到下,从左到右“,若将 index.wxss 中 container 的 border 颜色设置为 yellow,那么就会覆盖 assets.wxss 中的border 设置
内联样式
<!--index.wxml-->
<view style="width:500rpx; height:30px; background-color:{{colorValue}};">
Hello,world!
</view>
- class :静态样式
- style :动态样式
//index.js
Page({
data:{
colorValue: 'red'
}
})
选择器
选择器 | 样例 | 样例描述 |
---|---|---|
.class | .intro | 选择所有拥有 class="intro" 的组件 |
#id | #firstname | 选择拥有 id="firstname" 的组件 |
element | view | 选择所有 view 组件 |
element, element | view, checkbox | 选择所有文档的 view 组件和所有的 checkbox 组件 |
::after | view::after | 在 view 组件后边插入内容 |
::before | view::before | 在 view 组件前边插入内容 |
选择器优先级
选择器 | 权重 |
---|---|
!important(提升选择器的权重,严格来讲不是选择器) | ∞ |
style(标签内联属性,也可以理解为一个选择器) | 1000 |
#element(id 选择器) | 100 |
.element(class 选择器) | 10 |
element(元素标签选择器) | 1 |
!important 权重最高,会破坏掉样式表中固有的权重值比较规则,使得调试 bug 变得更加困难,因此使用时应当谨慎
!important 使用案例:
/** index.wxss **/
.title {
color: red !important;
}
JavaScript
JavaScript介绍
JavaScript是一种轻量的、解释型的、面向对象的头等函数语言,是一种动态的基于原型的多范式的脚本语言,支持面向对象、命令式和函数式的编程风格。
图书推荐:
小程序JavaScript实现
不同环境中的 JavaScript 对比
Nodejs 中的 JavaScript
- ECMAScript
- Native:原生模块,通过 Native 使用 JavaScript 不具备的能力
- NPM:包管理系统
小程序中的 JavaScript
- ECMAScript
- 小程序框架
- 小程序API
- 无法使用 jQuery 和 Nodejs 中的 Native 、NPM
浏览器中的 JavaScript
- ECMAScript
- DOM:浏览器的文档对象模型,是 HTML 和 xml 的应用程序接口,通过 js 读取当前网页的 DOM 对象
- BOM:浏览器的对象模型,处理浏览器的窗口和框架
小程序宿主环境差异
IOS | Android | IDE |
---|---|---|
JavaScriptCore | X5内核 | nwjs |
WXS
WXS 介绍
wxs(WeiXin Script),和 wxml 共同构建页面视图的结构内容
WXS 特性
模块
wxs 有独立的作用域,其中定义的变量和函数默认是私有的
<!--index.wxml-->
<wxs module="m1">
module.exports = {
message: 'Hello,world!'
}
</wxs>
<view> {{m1.message}} </view>
module.exports 属性:将 wxs 中的变量暴露,让外部可调用
<!--index.wxml-->
<wxs src="./m2.wxs" module="m2"></wxs>
<view> {{m2.message}} </view>
// m2.wxs
module.exports = require('./m1.wxs')
// m1.wxs
module.exports= {
message: "hello world!"
}
- src :声明外部 wxs 文件路径
- module :声明所使用的外部 wxs 文件中的模块名
- require() 函数 :在 wxs 中引用其他 wxs 文件
注意:尽量不要重复声明模块名,否则后面定义的模块会覆盖前面的模块
变量
与 ES5 标准的 JavaScript 变量用法一致
注释
<!--index.wxml-->
<wxs module+"m3">
var v = 1;
module.exports.value = v;
//单行注释
/*多行注释
v += 1;
*/
console.log(v);
/*
var d = 3;
console.log(d);
*/
</wxs>
<view> {{m3.value}} </view>
运算符
wxs 中运算符语句与 JavaScript 基本一致,但不支持 try ... catch 语句
运算符 | |
---|---|
基本运算符 | |
一元运算符 | |
位运算符 | |
比较运算符 | |
等值运算符 | |
赋值运算符 | |
二元逻辑运算符 |
数据类型
数据类型 | |
---|---|
number | 数字 |
string | 字符串 |
boolean | 布尔 |
object | 对象 |
array | 数组 |
function | 函数 |
date | 日期 |
regexp | 正则 |
- 生成 date 对象使用 getdate() 函数
- 生成 regexp 对象使用 getregexp() 函数
基础类库
基础类库 | |
---|---|
Number | |
Date | |
Global | |
console | |
Math | |
JSON |
与 ES5 标准的 JavaScript 基础类库基本一致,区别在于:
console 基础类库只提供 console.log()
date 基础类库只提供
date.pase() :解析字符串形式的日期时间,返回 UNIX 时间戳
date.now() :返回当前日期时间的 UNIX 时间戳
date.utc() :返回指定时间的 UNIX 时间戳
MINA 框架
小程序开发框架
小程序运行机制
启动
热启动
将后台切换到前台
冷启动
首次启动或被微信销毁后再次启动
若冷启动时发现有新版本,则异步下载新版代码包
加载
小程序启动时,向 CDN 请求最新的代码包,首次启动时,需等待代码包下载完毕,并注入到 web view 容器内执行之后,才能看到小程序的页面;客户端会将代码包缓存到本地,下次启动时,首先从 CDN 请求是否有最新版本代码包,若有,运行旧版本代码包的同时,异步下载最新版代码包。
CDN
内容分发网络,作用是将请求的内容分发到最近的网络节点服务器,提高用户访问的响应速度和成功率,解决带宽、服务器性能带来的延迟问题
生命周期
应用生命周期
首次启动时,客户端会初始化小程序的运行环境,同时从 CDN 下载,或从本地缓存拿到代码包,并注入到运行环境;
onLaunch:初始化完毕后,客户端会给逻辑层 App.js 的 app 实例派发 onLaunch 事件
onHide:当点击小程序右上角关闭,或点击手机 Home 键时,小程序被切入后台,这时调用 onHide
onShow:从后台重新打开小程序时,调用 onShow
onError:发生脚本错误,或 API 调用失败时,调用 onError,这时会给 onError 方法中传入一些错误信息
globalData:表示小程序应用的全局数据
页面生命周期
onLoad:页面初次加载时,客户端派发 onLoad 事件,在页面被销毁之前,只调用一次
onShow:页面打开后,或从另一个页面返回当前页面时,当前页的 onShow 方法被调用
onReady:当页面初次渲染完之后,调用 onReady 方法,在页面被销毁之前,只调用一次;onReady 触发之后,逻辑层就可以和视图层进行交互了
onHide:当打开新页面时,当前页的 onHide 方法被调用
onUnload:关闭当前页面时调用
data:表示当前小程序的页面数据
案例
页面路由
在一个多页面的小程序中,所有页面路由由框架进行管理,框架以栈的形式维护小程序的页面
路由方式 | 页面栈表现 |
---|---|
初始化 | 新页面入桟 |
打开新页面 | 新页面入桟 |
页面重定向 | 当前页面出桟,新页面入桟 |
页面返回 | 页面不断出桟,直到目标返回页,新页面入桟 |
Tab 切换 | 页面全部出桟,只留下新的 Tab 页面 |
重加载 | 页面全部出桟,只留下新的页面 |
路由触发方式以及对应页面生命周期函数
路由方式 | 触发时机 | 路由前页面 | 路由后页面 |
---|---|---|---|
初始化 | 小程序打开的第一个页面 | onLoad onShow | |
打开新页面 | 调用 API wx.navigateTo 或使用组件 < navigator open-type="navigateTo"/> | onHide | onLoad onShow |
页面重定向 | 调用 API wx.redirectTo 或使用组件 < navigator open-type="redirectTo"/> | onUnload | onLoad onShow |
页面返回 | 调用 API wx.navigateBack 或使用组件 < navigator open-type="navigateBack"/> | onUnload | onShow |
Tab 切换 | 调用 API wx.switchTab 或使用组件 < navigator open-type="switchTab"/> | 各种情况参考下表 | |
重启动 | 调用 API wx.reLaunch 或使用组件 < navigator open-type="reLaunch"/> | onUnload | onLoad onShow |