云开发练手项目:音乐播放器(下)

本文目录:

  • 1.冷启动与热启动
  • 2.小程序里不要频繁的进行setData
  • 3.小程序的更新机制
  • 4.小程序性能与体验优化
  • 5.场景值scene的作用与应用场景
  • 6.页面收录sitemap.json的作用与使用方法
  • 7.云开发小程序上限审核流程
  • 8.轮播图图片
  • 9.歌单信息管理
  • 10.发现信息管理
云开发练手项目:音乐播放器(下)_第1张图片
网页开发和小程序开发的主要区别.png

云开发练手项目:音乐播放器(下)_第2张图片
小程序运行环境.png

在不同的运行环境下,逻辑层和渲染层的运行位置都不同,所以在小程序开发中,要多用真机去进行调试。
小程序的开发其实就是典型的客户端原生与web技术结合的混合技术(Hybrid)

1.冷启动与热启动

第一次打开小程序,虽然以前打开过,但是数据被小程序主动销毁了,再次启动也算是冷启动,热启动:已经打开了,在一定时间内再次打开(大约5分钟),这时候的打开只是从后台切换到前台。


云开发练手项目:音乐播放器(下)_第3张图片
冷启动与热启动.png

2.小程序里不要频繁的进行setData

不表现在页面上的数据,不需要定义在data中。直接定义全局变量就行了。因为每次setData都会触发渲染层和系统层、逻辑层的通信。


云开发练手项目:音乐播放器(下)_第4张图片
小程序的渲染逻辑.png

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.云开发小程序上限审核流程

微信公众平台=》版本管理
首先需要把项目提交成”体验版”,项目预览只有项目成员才可以扫描二维码进行预览,小程序成为“体验版”
微信开发者工具右上角有个按钮”上传”,上传之后就生成了体验版,微信公众平台的版本管理中就有了对应的“开发版本”。

云开发练手项目:音乐播放器(下)_第5张图片
项目架构图_20191226105049.png

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

云开发练手项目:音乐播放器(下)_第6张图片
请求参数与返回值_20191227171811.png

我们把请求获得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的值是个数组,可以配置多个。

你可能感兴趣的:(云开发练手项目:音乐播放器(下))