137-3385-8848(同微信)

怎么制作唱吧小程序,类似唱吧的小程序开发文档

2022-04-21 管理员

唱吧小程序开发上线还不到一个月的时间,唱吧小程序通过借助小程序的用完即走特性,使小程序用户数突破200万,下面就以最近接触到的一款小程序为例,简单总结一下小程序底层框架和一些api接口方面的设计思路。

目录
  • 1、唱吧小程序框架浅析
  • 2、唱吧小程序底层搭建

1小程序框架浅析

大家都说小程序体验好,即开即用,和普通Webview渲染的H5相比页面启动速度、流畅度等方面好很多,这个问题我认为需要从几个方面考虑,首先,抛开产品业务层面的设计和优化,就是小程序底层框架的设计和实现方面的特点。

当我们新建或打开一个小程序项目(以唱吧比赛小程序为例),即可看到如下图的项目结构。

小程序入口文件为app.js, 全局样式文件为app.wxss,全局配置文件为app.json, 每个页面中再分视图wxml,wxss和逻辑js、文件配置json等,从这里我们可以看出,整个小程序的上层框架,也就是大体分为视图层和逻辑层两个部分。 (摘自官方文档https://developers.weixin.qq.com/miniprogram/dev/framework/structure.html)

小程序采用的MINA框架,View层主要用来渲染页面结构,App Service层用来逻辑处理、数据请求、接口调用,它们在两个线程里运行,整个小程序是只有一个App Service的,并且整个小程序的生命周期内它是常驻内存的。View层主要使用WebView渲染,而App Service逻辑层是使用JSCore运行。

通信方面,View和AppService是双线程通信的,主要通过系统层的JSBridage进行通信,AppService把数据变化通知到View,表现方法也就是setData方法,触发View页面更新,View把触发的事件通知到AppService进行业务处理。

这里要说的是,小程序是没有DOM结构的,那么视图层的渲染是如何做到的呢,就是运行环境中会把pages中的WXML的节点树结构,转化为JS的对象,进行渲染,这也是小程序体验优于普通分享页面的一大原因,省去了很多关于浏览器DOM的操作,由JS运行环境之间进行渲染解析。

2唱吧小程序底层搭建

那么话说回来,基于良好的框架,这次在搭建唱吧小程序底层的时候,我们其实做了哪些事情呢。

首先,我们并没有进行纯Native层的搭建和改造,而是对上述提到的API层的一次的封装,尤其是在关于网络请求的改造和小程序启动的登录流程方面,我们前端团队尝试去做一些分层和优化。

  • 网络请求方面

首先网络请求优化方面,微信提供的请求接口基本长这样:


  1. wx.request({

  2.  url: 'test.php', //仅为示例,并非真实的接口地址

  3.  data: {

  4.     x: '' ,

  5.     y: ''

  6.  },

  7.  header: {

  8.      'content-type': 'application/json' // 默认值

  9.  },

  10.  success: function(res) {

  11.    console.log(res.data)

  12.  }

  13. })

是不是感觉和之前的某种请求模式很像,没错,就是古老的$.ajax,这时候我们又想起了ajax的回调地狱,如果页面的请求很多,请求的顺序还有限定,瞬间又是各种嵌套,可以说是要从请求到懵逼了。

所以为了解决回调地狱和同时优化请求代码逻辑,我们在封装wx.request的同时,我们在小程序开发中,引入了async/await语法糖,用到了来自facebook的regenerator模块(详情请戳:https://github.com/facebook/regenerator),async、await函数经babel编译后,再用regenerator-runtime模块用于提供功能实现,这一方面也得力于小程序支持ES6语法的编译。

实现过程中,单独用一个公共方法封装,返回wx.request的promise


  1. //wechat.js

  2.  

  3. const request = (url,options) => {

  4.  return new Promise((resolve, reject) => {

  5.    wx.request({

  6.      url: url,

  7.      method: options.method,

  8.      data: Object.assign({}, options.data),

  9.      header: options.header,

  10.      success: resolve,

  11.      fail: reject

  12.    })

  13.  })

  14. }

之后在我们的上层公共库中,编写与请求相关的处理逻辑。


  1. // changba.js

  2.  

  3. const regeneratorRuntime = require('./regenerator-runtime.js')

  4. const wechat = require('./wechat')

  5. const URI = 'xxx'

  6.  

  7. const requestAPI = async (url,opt) => {

  8.  const app = getApp()

  9.  let options = Object.assign({data: {}},opt)

  10.    if (/^\/api\/(.+)$/.test(url)) {

  11.        url = URI + url;

  12.    }

  13.    if (!options.method) {

  14.        options.method = 'POST';

  15.    }

  16.    let header = {

  17.        'Content-Type': 'application/x-www-form-urlencoded'

  18.    }

  19.    options.header = options.header || header ;

  20.    //除了login方法  其余接口都要加入sessionInfo也就是后端加密过的session_key

  21.    if (!url.includes('/checkCode')) {

  22.      options.data['sessionInfo'] = app.globalData.sessionkey;

  23.    }

  24.    let isTimeout = false;

  25.    try {

  26.      const ree = await wechat.checkSession();

  27.    } catch (error) {

  28.      isTimeout = true;

  29.    };

  30.    try {

  31.      if (isTimeout) {

  32.        let aaa = await login(app);

  33.      }

  34.      wx.showLoading({

  35.        title: '加载中'

  36.      });

  37.        const res = await wechat.request(url,options)

  38.        if (res && res.statusCode) {

  39.            if (res.statusCode != 200) {

  40.                if (wx.hideLoading) {

  41.                    wx.hideLoading()

  42.                }

  43.                wx.showModal({

  44.                    content: wechat.errMsg(res.statusCode).message || '请求失败,请重新尝试',

  45.                    title: '提示',

  46.                    showCancel: false

  47.                })

  48.            } else {

  49.                if (res.data && res.data.code === 1) {

  50.                  if (wx.hideLoading) {

  51.                     wx.hideLoading()

  52.                  }

  53.                  return res.data

  54.                } else {

  55.                    // xxx 其他情况业务逻辑处理

  56.                }

  57.            }

  58.        }

  59.    } catch (error) {

  60.        console.log('请求异常信息:' + error)

  61.        if (wx.hideLoading) {

  62.          wx.hideLoading()

  63.        }

  64.        wx.showModal({

  65.            content: '请求信息异常',

  66.            title: '',

  67.            showCancel: false

  68.        })

  69.    }

  70. }

上述封装过程中,所以除了考虑到请求超时、检查用户身份等操作,还可以加入session过期等相关其他的业务处理逻辑,这也是自己搭建请求的好处,针对自己的业务需求,进行匹配和改造。

然而在经历这样两层封装之后,在写业务逻辑代码的过程中,就可以一目了然的发送请求了,达到逻辑清晰且书写自如,如果习惯了fetch以及axios的朋友应该都会比较喜欢这种方式。


  1.   async getdata() {

  2.     let self = this;

  3.     let cb_getdata = await app.changba.requestAPI('/api/xxx', { data: { id: self.data.id } });

  4.     if (cb_getdata && cb_getdata.code === 1) {

  5.           // xxx

  6.     }

  7.   }

  • 登录流程方面

下面说下,启动小程序后的登录流程方面,在这一方面,小程序与其他不同的是,没有固定的登录启动页面,而是完全后台交互,当然根据产品定位和需求,也可以自己做一套登录系统~

上一篇:类似美团商城小程序系统功能开发
下一篇:百度智能小程序开发文档简介
相关资讯 Releva ntnews
解决方案 Solutions
相关热点 Hot spot
郑州做排名中正确使用关键词优化的方法
  1. 我们的优势
  2. 我们的实力
  3. 选择我们的理由
咨询电话(微信同号)

137-3385-8848(同微信)

豫ICP备16014343号-1

Copyright © 2017-2022 版权所有 酷微科技 Rights Reserved

电话咨询 在线咨询 服务项目 SEO优化