-
小程序并非是直接通过 URL 访问的,而是通过信道服务进行通信和会话管理,所以它不支持 Cookie 存储,同时访问资源使用 wx.request 则不存在跨域的问题
-
小程序的整体框架采用面向状态编程方式,状态管理从 API 来看采用类似 Redux 的设计方式;单向数据绑定方式,当 View 在 Action 操作后,只能通过 Action 的业务处理来更新 View
-
behaviors是多重继承的,所以说,如果重复定义方法的话,后面的继承会覆盖前面的继承。
-
在引入缓存机制的时候最好清除缓存,防止异常情况
- 同理,小程序上线时,要记得清除缓存,避免造成问题,可以用开发工具的清除也可以调用API
- 缓存还是不缓存(认真考虑,大部分的小程序该缓存的没有缓存,偷懒)
-
在app.json里面编写page可以快速生成四个文件
-
页面之间传递数据的方式
- url传参
- 全局变量
- 缓存
- 发射事件,接受事件,类似angular,适合对象之类的复杂数据
-
充分利用ES6的优势,简写代码,比如扩展运算符,属性值简写,方法简写,箭头函数
- https://github.com/airbnb/javascript (推荐airbnb规范)
- 能用const就用const,const比let效率要高一些
-
注意
wx:key=“id” wx:for="{{books}}"
的写法- 列表是object 不重复,数字或者是字符串
- 如果列表本身是数字或者是字符串,可以
wx:key="*this"
-
插槽slot的优点,可以让组件内部的某一元素完全由组件的调用方来决定
-
小程序外部样式
externalClasses
不能覆盖之前已经存在的样式(默认样式),因为先后顺序不确定,很尴尬,版本v1.02.1811290!importent
-
逻辑层和视图层通过微信的
JSBridge
来实现通信的,逻辑层数据变化通过JSBridge
通知视图层,触发视图层更新;当视图层触发事件,则继续通过JSBridge
将事件通知到逻辑层做处理,如此交互进行。JSBridge
在三个环境(开发者工具、iOS 和 Android)中实现机制不同,在调用 Native 能力时主要使用invokeHandler
:- 开发者工具:通过
window.postMessage
来封装 - iOS:通过 WKWebview 的
window.webkit.messageHandlers.invokeHandler.postMessage
- Android:通过
WeixinJSCore.invokeHandler
- 开发者工具:通过
-
在消息分发的时候,则使用
publishHandler
:- 开发者工具:通过
addEventListener('message')
来监听消息,然后处理分发 - iOS:使用 WKWebview 的
window.webkit.messageHandlers.publishHandler.postMessage
- Android:通过
WeixinJSCore.publishHandler
- 开发者工具:通过
-
promise解决了纯粹callback(每层都要传递callback)很多的问题,比如常说的回调地狱,还有多个异步等待合并等等
- promise不需要层层传递callback的原因是没有剥夺函数return的能力,可以保存状态。更模糊的说,promise相当于一个对象,而不是一个函数
-
wxs在html中写js代码
- wxs拥有自己独立的运行环境,和js其实没有太大的关系。
-
小程序启动时,会同时启动两个线程,一个负责页面渲染的 WebView(实际不止一个,后面讲解),一个负责逻辑的 JavaScriptCore。逻辑层初始化后会将初始化数据(app.js 中的 global data)通过 JSBridge 传递给渲染层进行渲染,渲染层 WebView 页面渲染完之后又会跟逻辑层通信。
但是小程序中有大量的API是非Promise风格的,这样我们怎么链式调用呢? 我们可以把小程序回调函数转换成promise(闭包)
const promise=new Promise((resolve,reject)=>{
// pending(进行中) fulfilled(已成功) rejected(已失败)凝固(不能再改变状态)
wx.getSystemInfo({
success:res=>resolve(res), // 简写
fail:(error)=>{
reject(error)
}
})
})
// 可以随时通过promise拿到异步调用结果
promise.then((res)=> {
conso.loeg(res)
},(error)=> {
console.log(res)
}
})
示例:(重构http基础方法)
原方法
import { config } from '../config.js'
class HTTP {
constructor() {
this.baseRestUrl = config.api_blink_url
}
//http 请求类, 当noRefech为true时,不做未授权重试机制
request(params) {
var that = this
var url = this.baseRestUrl + params.url;
if (!params.method) {
params.method = 'GET';
}
wx.request({
url: url,
data: params.data,
method: params.method,
header: {
'content-type': 'application/json',
'appkey':config.appkey
},
success: function (res) {
// 判断以2(2xx)开头的状态码为正确
// 异常不要返回到回调中,就在request中处理,记录日志并showToast一个统一的错误即可
var code = res.statusCode.toString();
var startChar = code.charAt(0);
if (startChar == '2') {
params.success && params.success(res.data);
} else {
params.error && params.error(res);
}
},
fail: function (err) {
params.fail && params.fail(err)
}
});
}
};
export { HTTP };
import config from '../config.js'
const tips = {
1: '抱歉,出现一个错误',
1005: 'appkey无效'
}
class HTTP {
request({
url,
data = {},
method = 'GET'
}) {
return new Promise((resolve, reject) => {
this._request(url, resolve, reject, data, method)
})
}
_request(url, resolve, reject, data = {}, method = 'GET') {
wx.request({
url: config.baseUrl + url,
data: data,
method: method, // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: {
'content-type': 'application/json',
'appkey': config.APPKEY
}, // 设置请求的 header
success: (res) => {
const code = res.statusCode.toString()
if (code.startsWith('2')) {
resolve(res.data)
} else {
reject()
const error_code = res.data.error_code
this._show_error(error_code)
}
},
fail: (err) => {
reject()
this._show_error(1)
},
complete: function () {
// complete
}
})
}
_show_error(error_code) {
if (!error_code) {
error_code = 1;
}
const tip = tips[error_code]
wx.showToast({
title: tip ? tip : tips[1],
icon: 'none',
duration: 2000
})
}
}
export {
HTTP
}
示例:Promise是怎么解决回调地狱的
错误用法
const Res = bookModel.getHotList()
Res.then(
res => {
bookModel.getMyBooKCount()
.then(
res => {
bookModel.getMyBooKCount()
.then(
res => {
// do somethings
})
})
})
正确用法(平行)
const Res = bookModel.getHotList()
Res.then(
res => {
return bookModel.getMyBooKCount()
})
.then(
res => {
return bookModel.getMyBooKCount()
})
.then(
res => {
// do somethings
})
错误用法:层级回调
const Res = bookModel.getHotList()
Res.then(
res => {
bookModel.getMyBooKCount()
.then(
res => {
bookModel.getMyBooKCount()
.then(
res => {
// do somethings
})
})
})
- 当我们使用多个并行请求使用loading时,我们可以使用Promies.all来统一接收回调数据
- Promise.race只等待第一个数据请求完成,就会触发回调
- 页面监听是否滑动到最底部可以通过scroll-view或者是page onReachBottom两种方式完成
- scroll-view在早期时候是有问题的
- 当我们setData给子对象赋值时,可以把key用引号引起来赋值,但是这样赋值,view层是不响应的,所以不是很推荐这样写。