微信小程序有自带的api接口,wx.request();
不会跨域,因为微信小程序不是浏览器,没有同源策略的约束;
wx.request({
url: 'https://xxxxxxx.com/api',
method: "POST",
data: {
pageNum: 1,
pageSize: 10
},
header: {
"content-type": "application/x-www-form-urlencoded"
},
success: res => {
console.log(res)
}
})
引用数据 {{}}
逻辑渲染 wx:if wx:elif wx:else hidden
列表渲染 wx:for wx:for-item wx:for-index wx:key,使用 wx:for-item 指定数组当前元素的变量名,使用 wx:for-index 指定数组当前下标的变量名。
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName"></view>
驱动视图 this.setData({})
事件绑定 bind
优点:①容易推广。在微信中,小程序拥有众多入口,且微信用户基数大,这些都有助于推广小程序;②使用便捷。微信下拉即可打开小程序列表,点击即可使用小程序,不需要额外的安装操作等;③体验良好。小程序不会像H5页面一样经常出现卡顿、延时、加载慢、权限不足等问题;④成本更低,从开发成本到运营推广成本,小程序的花费仅为APP的十分之一。
缺点:①单个包大小限制为2M,这导致无法开发大型的应用,采用分包最大是20M;②需要像app一样审核上架,这点相对于H5的发布要麻烦一些;③处处受微信限制。例如不能直接分享到朋友圈,涉及到积分,或者虚拟交易的时候,小程序也是不允许的。
这篇文章有更详细的解释
浏览器中的JS:ES,DOM,BOM
ES: ECMAScript、 DOM : 文档对象模型、 BOM : 浏览器对象模型;
Node 中的JS:ES,NPM,Native
Native就是原生的模块,通过这个模块来使用JavaScript语言本身不具有的一些能力(来自百度:native方法简单的讲,即Java调用非Java代码的接口)。
NPM是包管理系统、NPM是目前最大的开原库生态系统,通过各种NPM扩展包快速的实践一些功能。
直观的说小程序中没有DOM和BOM对象,也无法对npm包进行管理
浏览器中渲染是单线程的;
而在小程序中的运行环境分成渲染层和逻辑层, WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
小程序的渲染层和逻辑层分别由2个线程管理:
渲染层的界面使用了WebView 进行渲染;
逻辑层采用JsCore线程运行JS脚本。
一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端(Native)做中转。
小程序中的生命周期函数,分为 应用生命周期函数 和 页面生命周期函数 ;
应用生命周期函数有:
onLaunch 函数的参数也可以使用 wx.getLaunchOptionsSync
获取;
onShow 也可以使用 wx.onAppShow
绑定监听;
onHide 也可以使用 wx.onAppHide
绑定监听;
App.js是小程序入口文件,所以在App.js中调用应用生命周期函数:
App({
// 小程序初始化完成时,执行此函数,可以做一些初始化的工作
onLaunch: function( options ){}
// 小程序显示到屏幕上的时候,执行此函数
onShow: function( options ){}
// 小程序被最小化的时候,执行此函数
onHide: function(){}
})
还有一个不太常用,但还是挺有作用的应用生命周期函数:onError(String error)
,在小程序发生脚本错误或 API 调用报错时触发。也可以使用 wx.onError
绑定监听。
还有其他不常用的应用生命周期函数,可以参考:官方文档
页面生命周期函数有:
onLoad函数有一个参数:onLoad(Object query)
还有其他比较常用的,如下图红框内容:
小程序中使用bind关键字绑定事件,但小程序中不能在绑定事件的同时为事件处理函数传递参数,可以为组件提供 data-* 自定义属性传参,其中 * 代表的是参数的名字。
<button bindtap="tapTap" data-param="{{"事件传参"}}">事件传参button>
接收传递到的参数:
tapTap(e){
console.log(e.currentTarget.dataset.param)
// 打印结果为:事件传参
}
WXSS和CSS类似,不过在CSS的基础上做了一些补充和修改。
@import
标识符来导入外联样式。最常用的两个页面的跳转和传参方式:①wx.navigateTo ②navigator标签
wx.navigateTo({
url: `/pages/details?id=${xxx}`
});
<navigator url="/page/navigate/navigate?title=navigate" hover-class="navigator-hover">跳转到新页面navigator>
跳转页接收参数:
onLoad (options) {
console.log(options)
this.setData({
goodsId:options.id,
goodsName:options.name
})
}
其他方式:
wx.switchTab()
用来 跳转至tabBar页面,并关闭其他所有非 tabBar 页面
wx.redirectTo()
和 wx.navigateTo()
一样,都 跳转至非tabBar页面,但会关闭当前页面
wx.reLaunch()
也是 跳转至非tabBar页面,并且会关闭其他所有页面
wx.navigateBack()
用来返回上一页面或多级页面,并关闭当前页面。
wx.navigateBack({
delta: 2 //返回的页面数,1为返回上一页,如果delta大于现有页面数,则返回到首页。
})
小程序提供了读写本地数据缓存的接口,通过 wx.getStorage/wx.getStorageSync
读取本地缓存,通过 wx.setStorage/wx.setStorageSync
写数据到缓存,其中带Sync后缀的接口表示是同步接口
// 同步存储
wx.setStorageSync('key', 'value')
// 异步存储,并且开启加密存储
wx.setStorage({
key: "key",
data: "value",
encrypt: true, // 若开启加密存储,setStorage 和 getStorage 需要同时声明 encrypt 的值为 true
success() {
wx.getStorage({
key: "key",
encrypt: true, // 若开启加密存储,setStorage 和 getStorage 需要同时声明 encrypt 的值为 true
success(res) {
console.log(res.data)
}
})
}
})
// 同步读取缓存
var value = wx.getStorageSync('key')
// 异步读取缓存
wx.getStorage({
key: 'key',
success (res) {
console.log(res.data)
}
})
小程序宿主环境会管理不同小程序的数据缓存,不同小程序的本地缓存空间是分开的,每个小程序的缓存空间上限为10MB,如果当前缓存已经达到10MB,再通过wx.setStorage写入缓存会触发fail回调。
小程序的本地缓存不仅仅通过小程序这个维度来隔离空间,考虑到同一个设备可以登录不同微信用户,宿主环境还对不同用户的缓存进行了隔离,避免用户间的数据隐私泄露。
由于本地缓存是存放在当前设备,用户换设备之后无法从另一个设备读取到当前设备数据,因此用户的关键信息不建议只存在本地缓存,应该把数据放到服务器端进行持久化存储。
在小程序开发过程中,我们可能会进行许多的网络请求,如果每次请求都去写一遍 request 代码:
wx.request({
url: 'xxx',
data: {
a: '',
b: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success(res) {
console.log(res.data)
},
fail(err){
console.log(err)
}
})
效率低下且不便于维护,所以封装一下 wx.request
接口还是有必要的。
通常以返回 promise 对象的形式进行请求的封装:
const baseUrl = "123456.com"
function request(method, url, dataObj) {
return new Promise(function(resolve, reject) {
let header = {
'content-type': 'application/json',
};
wx.request({
url: baseURL + url,
method: method,
data: dataObj.data,
header: dataObj.header||header,
success(res) {
//请求成功
if (res.code == 0) {
resolve(res);
} else {
//其他异常
reject('运行时错误,请稍后再试');
}
},
fail(err) {
//请求失败
reject(err)
}
})
})
}
封装之后代码统一管理,方便维护,节省时间,提高了工作效率!
微信小程序中使用 setData
函数把变量渲染到视图层
注意:
示例:
Page({
data: {
testOne: 1,
testTwo: 2
},
onLoad: function() {},
onShow () {
this.setData({
test02:8
})
console.log(this.data.testTwo)
}
},
})
获取网络状态(2G/3G/4G/5G/WIFI…)
Page({
// 点击“预览文档”的按钮,触发tap回调
tap: function() {
wx.getNetworkType({
success: function(res) {
// networkType字段的有效值:
// wifi/2g/3g/4g/5g/unknown(Android下不常见的网络类型)/none(无网络)
if (res.networkType == 'wifi') {
// 从网络上下载文档
wx.downloadFile({
url:' https://lark-temp.oss-cn-hangzhou.aliyuncs.com/__temp/464110/docx/bb5d8e7d-97bc-406b-be94-ca2b4724c0e6.docx?OSSAccessKeyId=LTAI4GKnqTWmz2X8mzA1Sjbv&Expires=1644944885&Signature=qUYOtNWZOaopjkEFbcKpvgmn%2B1U%3D',
success: function (res) {
// 下载成功之后进行预览文档
wx.openDocument({
filePath: res.tempFilePath
})
}
})
} else {
wx.showToast({ title: '当前为非Wifi环境' })
}
}
})
}
})
扫码能力
Page({
// 点击“扫码订餐”的按钮,触发tapScan回调
tapScan: function() {
// 调用wx.login获取微信登录凭证
wx.scanCode({
success: function(res) {
var num = res.result // 获取到的num就是餐桌的编号
}
})
}
})
分享能力(分享到朋友圈或个人聊天等)
Page({
onShareAppMessage(){
// 我们要记录转发的记录
return {
// 分享的标题
title:'网友热议',
// 分享的封面, 默认为当前页面的截图
imageUrl:"/assets/icon/index.png",
// 点击分享跳转的路径,默认是当前路径,也可以自定义配置,添加额外的跳转参数 path:"/pages/index/index?userId=10&entry=share"
}
}, // 省略了别的属性 ...})
wx.canIUse(string schema)
判断小程序的API、回调、参数、组件等是否在当前版本可用
wx.getSystemInfoSync() | wx.getSystemInfo()
获取系统信息
wx.getUserProfile(Object object)
获取用户信息。页面产生点击事件(例如 button 上 bindtap 的回调中)后才可调用,每次请求都会弹出授权窗口,用户同意后返回 userInfo。该接口用于替换 wx.getUserInfo
示例代码截取自此篇文章
父传子的不同点是:微信小程序在子组件中接受父组件传 用 propertites 进行接收,而不是 props
properties: {
msg:{
// type 要接收的数据的类型
type:String,
// value 默认值
value:""
},
},
子传父的不同点是:微信小程序在子组件中使用 triggerEvent
抛出自定义事件名,而不是 this.$emit()
methods: {
sendData() {
console.log(this.data.msg)
this.triggerEvent('eventName', '要传递的参数')
}
}
behaviors 是用于组件间代码共享的特性,类似于一些编程语言中的 mixins
或 traits
。
每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。 每个组件可以引用多个 behavior ,behavior 也可以引用其它 behavior 。
组件引用时,在 behaviors 定义段中将它们逐个列出即可。
代码示例:
// my-component.js
var myBehavior = require('my-behavior')
Component({
behaviors: [myBehavior],
properties: {
myProperty: {
type: String
}
},
data: {
myData: 'my-component-data'
},
created: function () {
console.log('[my-component] created')
},
attached: function () {
console.log('[my-component] attached')
},
ready: function () {
console.log('[my-component] ready')
},
methods: {
myMethod: function () {
console.log('[my-component] log by myMethod')
},
}
})
截取自简书原文,学到了
包体积优化
分包加载(优先采用,大幅降低主包体积)。
图片优化(1.使用tinypng压缩图片素材; 2.服务器端支持,可采用webp格式)。
组件化开发(易维护)。
减少文件个数及冗余数据。
请求优化
首次渲染优化
思路:把屏幕分为左右两个容器,根据容器的高度决定下一个元素应该放在哪个容器内(高度相对较低的容器)。
代码如下:
// 处理数据
initList(list) {
this.data.finish = false
// 临界值
if (list.length == 0) {
this.data.finish = true
return
}
let item = list.shift()
wx.getImageInfo({
src: item.coverImgUrl,
success: (res) => {
if (this.data.leftHeight <= this.data.rightHeight) {
// 默认从左往右渲
this.data.leftList.push(item)
this.data.leftHeight += res.height / res.width
} else {
this.data.rightList.push(item)
this.data.rightHeight += res.height / res.width
}
this.setData({
leftList: this.data.leftList,
rightList: this.data.rightList,
})
},
complete: () => {
this.initList(list)
}
})