本文目录:
- 1.冷启动与热启动
- 2.小程序里不要频繁的进行setData
- 3.小程序的更新机制
- 4.小程序性能与体验优化
- 5.场景值scene的作用与应用场景
- 6.页面收录sitemap.json的作用与使用方法
- 7.云开发小程序上限审核流程
- 8.轮播图图片
- 9.歌单信息管理
- 10.发现信息管理
在不同的运行环境下,逻辑层和渲染层的运行位置都不同,所以在小程序开发中,要多用真机去进行调试。
小程序的开发其实就是典型的客户端原生与web技术结合的混合技术(Hybrid)
1.冷启动与热启动
第一次打开小程序,虽然以前打开过,但是数据被小程序主动销毁了,再次启动也算是冷启动,热启动:已经打开了,在一定时间内再次打开(大约5分钟),这时候的打开只是从后台切换到前台。
2.小程序里不要频繁的进行setData
不表现在页面上的数据,不需要定义在data中。直接定义全局变量就行了。因为每次setData都会触发渲染层和系统层、逻辑层的通信。
3.小程序的更新机制
我们可以在app.js的onLaunch生命周期中,添加代码,进行版本的检查和更新,把下面这个函数放在onLaunch()里面,让小程序启动的时候就检查更新。
checkUpdate() {
const updateManager = wx.getUpdateManager()
// 检测版本更新
updateManager.onCheckForUpdate((res) => {
// 如果有版本更新的话
if (res.hasUpdate) {
updateManager.onUpdateReady(() => {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用',
// 如果用户选择的是确定
success(res) {
updateManager.applyUpdate()
}
})
})
}
})
}
4.小程序性能与体验优化
- 合理设置可点击元素的响应区域大小
- 避免渲染页面耗时过长
- 避免执行脚本时间过长
- 对网络请求做必要的缓存以避免多余的请求
- 不要引入未被使用的wxss样式
- 所有资源请求建议使HTTPS,更加安全
- 不要使用废弃接口
- 避免过大的WXML节点数目
- 一个页面少于1000个WXML节点
- 节点数深度少于30层
- 子节点数量不大于60个
- 避免将不可能被访问到的页面打包在小程序包里
- 及时回收定时器(小程序中的定时器都是全局的,不会随便页面切换而消失)
- 避免使用:active伪类来实现点击态(使用navigator组件)
- 滚动区域可开启惯性滚动以增强体验
IOS上:-webkit-overflow-scrolling:touch
- 避免出现任何的Javascript异常
- 所有请求的耗时不应该太久,请求最好都要加上showloading,不要让页面处于假死状态
- 避免短时间内发起太多的图片请求
- 避免短时间内发起太多请求
setData的优化
- 避免setData的数据过大(小程序的限制是每次1M以内)
- 避免setData的调用过于频繁
- 避免将未绑定到WXML的变量传入setData
setData是一个异步操作,this.data是同步操作,setData的回调是所有同步任务完成后才去执行,但是this.data的值我们可以直接拿到进行使用
案例1:下面代码的执行顺序是什么?
test的初始值是0
console.log('test开始:'+this.test)
this.setData({
test:1
},()=>{
console.log('回调执行')
})
console.log('test设置后:’+this.test)
for (let i =0;i<10000;i++){
for(let j=0;j<10000;j++){}
}
console.log('长耗时:'+this.test)
//test开始:0
//test设置后:1
//test长耗时:1
//回调执行
案例2:setData改变对象的属性值
testObj的默认属性为name:zhangsan,age:27
changeAge(){
this.setData({
testObj:{
age:28
}
})
}
如果直接像上面这样设置的话,age属性值确实是变了,但是name属性就消失了,正确的做法应该是
changeAge(){
this.setData({
['testObj.age']:{
age:28
}
})
}
setData改变的值可以不事先在data中进行定义,但是建议所有需要setData并且在页面上显示的值都在data中进行定义。
小程序开发的性能检查:测试器中有个界面是Audits,我们开始检查后将页面的所有功能都手动操作一遍,然后点击Stop就会出现响应的评分,A是最好的
5.场景值scene的作用与应用场景
有几十种途径可以进行到小程序,每个途径对应着一个ID值,如扫描二维码对应的是1011,长按图片识别二维码对应的1012
我们可以通过对应的代码设置,来实现根据不同的入口场景,来实现页面的分流,同时也可以很方便的进行后期的数据统计。
在app.js中对应的生命周期onShow()中添加代码(onShow监听小程序的启动和切前台)
开发者工具的导航栏有个功能键“切后台”,点击后可以模拟小程序切入后台,然后可以选择不同的场景来进行小程序
onShow(options){
}
onLauch:监听小程序的初始化
onShow:监听小程序的启动和切换前台
这两个的options的结构是一样的,里面都有scene字段
options可以打印出来scene值,根据这个值的不同我们可以进行不同的设置,同时onLaunch生命周期中有可以进行打印,有几个特定的场景代表着来源是外部的应用(其他小程序或者公众号),如果是的话,options的referrerInfo字段会出现appid值,对我们也很有用。
6.页面收录sitemap.json的作用与使用方法
在sitemap没出现之前,小程序的搜索只能通过分类的名称,sitemap让小程序的搜索也可以根据页面内容实现。(本质就是小程序的搜索功能优化)
小程序的官网设置页面,有一个页面收录功能开关按钮,默认是开启的
项目文件里默认创建有sitemap.json,我们可以里面添加和改变配置,在page里面配置页面,*代表所有页面。页面参数params以及匹配规则matching都是可以自由配置的。
"action":"allow"//允许被索引
"action":"disallow"//不允许被索引
7.云开发小程序上限审核流程
微信公众平台=》版本管理
首先需要把项目提交成”体验版”,项目预览只有项目成员才可以扫描二维码进行预览,小程序成为“体验版”
微信开发者工具右上角有个按钮”上传”,上传之后就生成了体验版,微信公众平台的版本管理中就有了对应的“开发版本”。
GitHub上搜索vue-element-admin,star最多的那个,我们选择使用基础模板vue-admin-template
克隆项目
git clone https://github.com/PanJiaChen/vue-admin-template.git
进入项目目录
cd vue-admin-template
安装依赖
npm install
建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org
启动服务
npm run dev
问题:下载了之后npm run dev报错,去掉vue.config.js中的open:true之后可以直接启动,但是登陆报405错误。
后端框架我们选用koa
1.建立空文件夹
2.npm init -y
3.npm install koa
4.新建app.js作为入口文件
在nodejs中出现最多的就是异步操作
实现hello world
const Koa = require('koa')
const app = new Koa()
app.use(async (ctx)=>{
ctx.body = 'hello world'
})
app.listen(3000)
选用request来实现后端的发送请求
npm install request
npm install request-promise
获取access_token的请求接口
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
我们把请求获得token的代码封装在utils文件夹中的getAccessToken.js文件中
const rp = require('request-promise')
const APPID = 'xxxx'
const APPSECRET = 'xxx'
const URL = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`
const updateAccessToken = async () => {
const resStr = await rp(URL)
const res = JSON.parse(resStr)
console.log(res)
}
updateAccessToken()
这时候通过运行getAccessToken.js文件我们可以在控制台上看到,我们已经获取到了token,并且有效时间为7200s,我们选择把获取到的token,通过node写入到json文件中去。
写入信息,需要引入fs和path两个核心模块,并且封装一个可以读取token的方法。同时读取代码的时候如果文件不存在,会报错,我们需要进行一个异常的捕获。完整代码如下
const rp = require('request-promise')
const APPID = 'xxx'
const APPSECRET = 'xxx'
const URL = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`
// 引入两个核心文件,一个用来读取文件,一个用来获得文件的绝对路径
const fs = require('fs')
const path = require('path')
// 定义我们要写入数据的文件路径
const fileName = path.resolve(__dirname, './access_token.json')
const updateAccessToken = async () => {
const resStr = await rp(URL)
const res = JSON.parse(resStr)
console.log(res)
// 写文件,writeFileSync第一个参数是要写入的文件路径,文件没有的话会自动创建,
//第二个参数是我们想要写入的值
//第二个参数我们写代码的时候定义的是对象,但是最终录入的是字符串,所以需要进行转换
if (res.access_token) {
fs.writeFileSync(fileName, JSON.stringify({
access_token: res.access_token,
createTime: new Date()
}))
}else{
// 如果因为网络原因,一次获取token失败也必须再次获取,因为后面的所有操作都要依赖这个token
updateAccessToken()
}
}
// 封装读取token的方法
const getAccessToken = async ()=>{
try {
// 读取文件
// 第二个参数utf8如果不传,则默认读取的是二进制数
const readRes = fs.readFileSync(fileName, 'utf8')
const readObj = JSON.parse(readRes)
console.log(readObj)
} catch (error) {
// 如果读取失败,就重新请求接口
await updateAccessToken()
// 然后再去获取token信息
await getAccessToken()
}
}
// updateAccessToken()
getAccessToken()
module.exports = getAccessToken
设置一个定时器,去获取token
setInterval(()=>{
await updateAccessToken()
},7200*1000)
路由规划
下载安装koa-router
npm install koa-router
新建controller文件夹,表示项目中C层(MVC模式),把前端发送过来的请求,我们进行云函数调用处理后再返还给前端=>这个文件夹的作用
在controller文件夹中新建一个playlist.js,关于歌单的处理写在这个文件中
此时的app.js代码
const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')
const router = new Router()
const playlist = require('./controller/playlist.js')
// 通过router声明路由名称, 对应的就是playlist里面的路由
router.use('/playlist', playlist.routes())
// 声明router
app.use(router.routes())
// 允许方法的调用
app.use(router.allowedMethods())
app.use(async (ctx) => {
ctx.body = 'hello world'
})
app.listen(3000, () => {
console.log('listening on 3000')
})
playlist.js代码
const Router = require('koa-router')
const router = new Router()
router.get('/list',async(ctx,next)=>{
// 查询歌单列表
ctx.body='歌单列表'
})
module.exports = router
启动项目,访问localhost:3000/playlist/list,我们就能看到“歌单列表”
接下来,在playlist.js中调用HTTP API触发云函数
这一步,我们实现访问localhost:3000/playlist/list可以把请求到的歌单信息展现到浏览器上,此时的playlist.js完整代码如下
const Router = require('koa-router')
const router = new Router()
const getAccessToken = require('../utils/getAccessToken.js')
const ENV = 'test-t1x7t'
const rp = require('request-promise')
router.get('/list', async (ctx, next) => {
const access_token = await getAccessToken()
// 查询歌单列表
const url = `https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=${access_token}&env=${ENV}&name=music`
// 用request-promise发送post请求的方式:定义一个options对象,然后将options作为发送请求的参数
const options = {
method: 'POST',
url: url,
body: {
// 首先我们需要告诉云函数中的tcb-router,我们要请求的具体路由
$url: 'playlist',
start: 0,
count: 50
},
json: true
}
ctx.body = await rp(options)
.then((res) => {
// console.log(res)
return JSON.parse(res.resp_data).data
})
.catch((err) => {
console.log("出错了")
})
})
module.exports = router
接下来我们要实现从前端项目发送请求到后端拿取这个json歌单列表数据
前端代码部分1.30左右
解决跨域的方案之一:cors
在后端项目中配置上允许发请求的域名
首先需要在后端项目安装corsnpm install koa2-cors
然后在app.js文件中进行导入const cors = require('koa2-cors')
进行配置
app.use(cors({
origin:['http://localhost:9528'],
credentials:true
}))
这样的话,我们就可以从http://localhost:9528发送请求了,origin的值是个数组,可以配置多个。