小程序一些功能

小程序-分包加载

目前小程序分包大小有以下限制:

  1. 整个小程序所有分包大小不超过 16M
  2. 单个分包/主包大小不能超过 2M

某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。

通俗理解,默认建立得quick项目,根目录下的所有文件就是一个独立的分包,大小不超过2M;

使用分包之后,在根目录下建立对应的目录文件,将对应的文件防止对应的目录下,并在 app.json  中声明 subpackages 字段即可

举个例子,现有一个由首页,最新动态 ,个人中心三块组成的,有三个tab切换的小程序。我们在设置分包时,一个tab设置一个分包,建立独立的文件夹,页面文件放置对应文件夹中

并配置subpackages  

假设支持分包的小程序目录结构如下:

├── app.js
├── app.json
├── app.wxss
├── packageA
│   └── pages
│       ├── cat
│       └── dog
├── packageB
│   └── pages
│       ├── apple
│       └── banana
├── pages
│   ├── index
│   └── logs
└── utils

开发者通过在 app.json subpackages 字段声明项目分包结构:

{

  "pages":[

    "pages/index",

    "pages/logs"

  ],

  "subpackages": [

    {

      "root""packageA",

      "pages": [

        "pages/cat",

        "pages/dog"

      ]

    }, {

      "root""packageB",

      "name""pack2",

      "pages": [

        "pages/apple",

        "pages/banana"

      ]

    }

  ]

}

subpackages 中,每个分包的配置有以下几项:

字段

类型

说明

字段

类型

说明

rootString分包根目录
nameString分包别名,分包预下载时可以使用
pagesStringArray分包页面路径,相对与分包根目录
independentBoolean分包是否是独立分包

注意: 主包便是除开定义的分包文件之外的余下文件,大小均不可超过2M

引用原则

  • packageA 无法 require packageB JS 文件,但可以 require app、自己 package 内的 JS 文件
  • packageA 无法 import packageB 的 template,但可以 require app、自己 package 内的 template
  • packageA 无法使用 packageB 的资源,但可以使用 app、自己 package 内的资源

低版本兼容

由微信后台编译来处理旧版本客户端的兼容,后台会编译两份代码包,一份是分包后代码,另外一份是整包的兼容代码。 新客户端用分包,老客户端还是用的整包,完整包会把各个 subpackage 里面的路径放到 pages 中。

功能-返回上一级页面并刷新(页面栈)

在很多列表查询详情的业务场景中,都需要返回上一级并刷新页面的操作,而在微信小程序中提供的方法 wx.navigateBack  方法中,返回上一级页面是不会刷新的。

如果页面的加载方法是在onload 中触发的话,那么可以将我们的方法调用修改至onShow方法中触发即可。

在小程序的生命周期中,onLoad只会加载一次,而onshow方法会在页面每次显示的时候加载。

注意:

如果上一级的页面是从上上级页面跳过来的话,在onLoad方法中,使用 options 获取参数的方法就要改为在onShow使用,并且此方法需要修改才能使用,我们可以使用页面栈的方式,获取上上级页面传来的参数

下面看代码示例:

/**

   * 生命周期函数--监听页面加载

   */

  onLoad: function (options) {

    var that = this;

    that.setData({

      id: options.id

    })

  },

修改成:

/**

  * 生命周期函数--监听页面显示

  */

 onShow: function () {

   // 页面初始化 options为页面跳转所带来的参数

   var that = this;

   let pages = getCurrentPages(); //页面栈

   let currPage = pages[pages.length - 1]; //当前页面

   that.setData({

     name: currPage.options.name //获取上上级页面传的参数

   })

 },

原生模板-封装路由文件和路由方法

小程序有5种路由方法的使用场景,本文封装了路由文件和路由方法,提升小程序体验和开发效率

需求产生的原因

  • 每次在代码中使用路由时,总是需要粘贴复制路径,当路径有修改时,需要修改对应所有使用到该路径的地方,维护成本高
  • 路由跳转拼接参数,当业务庞大时需要拼接十几个参数
  • 路由返回只会返回一层,不能直接返回目标页面,因为不知道目标页面是否在路由栈中,也不知道在第几层

封装路由文件,对路由进行通统一的管理

在utils文件夹下创建route.js

// 路由管理页面,在此统一配置

export default {

    'index':'pages/index/index',

    'logs':'pages/logs/logs',

    'list''pages/list/list'

}

所有路由均在上面的文件进行配置

封装路由方法

路由方法有五个,常用 的有三个 switchTab   navigateTo   navigateBack   

简单介绍一下这五个方法及使用场景

  • switchTab :跳转tabBar页面专用,其他页面出栈,新页面入栈
  • navigateTo :最常用的路由跳转,会加入到页面栈,允许返回,也就是新页面不断入栈
  • navigateBack :返回,只能返回到页面栈中存在的页面,页面不断出栈,直到到达目标页
  • redirectTo :  关闭当前页面,跳转某个页面,当前页面不会加入到页面栈,也就是说当前页面不能通过返回到达,比如付款页面,付款完成后,最好不要再让用户返回到付款页,再比如一些无法修改的操作,比如删除商品,商品删除后再通过navigateBack返回再删除一次商品,体验肯定不好,表现为当前页面出栈,新页面入栈
  • relaunch : 关闭所有页面,打开某个页面,可以打开任意页面包括tabBar,适合强制完成某个操作的页面,比如登录页,当已登录的用户点击退出后,进入登录页,那么就不能通过返回再回去了,就必须留下来登录或注册,适合用这个,表现为所有页面出栈,新页面入栈

开始封装,在utils目录创建UtilRoute.js 

// 封装路由方法

export default {

    /**

     * function

     * @param {string} url 目标页面的路由

     * @param {Object} param 传递给目标页面的参数

     * @description  处理目标页面的参数,转成json字符串传递给param字段,在目标页面通过JSON.parse(options.param)接收

     */

    navigateTo(url,param={}){

        if(param){

            url+=`?param=${JSON.stringify(param)}`

        }

        wx.navigateTo({

            url:url,

            fail(err) {

                console.log('navigateTo跳转出错',err)

            },

        })

    },

    /**

     * function

     * @param {string} url 目标页面的路由

     * @param {Object} param 传递给目标页面的参数,只有页面栈无目标页面调用navigateTo时,参数才会生效,单单返回不能设置参数

     * @description  先取出页面栈,页面栈最多十层,判断目标页面是否在页面栈中,如果在,则通过目标页的位置,返回到目标页面,否则调用navigateTo方法跳转到目标页

     */

    navigateBack(url,param={}){

        if(url) {

            const pagesList = getCurrentPages()

            let index =  pagesList.findIndex(e=>{

                return url.indexOf(e.route)>=0

            })

            if(index == -1){  // 没有在页面栈中,可以调用navigateTo方法

                this.navigateTo(url,param)

            }else{

                wx.navigateBack({

                    delta: pagesList.length-1-index,

                    fail(err){

                        console.log('navigateBack返回出错',err)

                    }

                })

            }

        else {

            wx.navigateBack()

        }

    },

    switchTab(url){ // 封装switchTab,switchTab不能有参数

        wx.switchTab({

            url:url

        })

    },

    redirectTo(url,param={}){ // 封装redirectTo,和navigateTo没啥区别

        if(param){

            url+=`?param=${JSON.stringify(param)}`

        }

        wx.redirectTo({

            url:url,

            fail(err) {

                console.log('redirectTo跳转出错',err)

            },

        })

    },

    reLaunch(url,param={}){ // 封装reLaunch,和navigateTo没啥区别

        if(param){

            url+=`?param=${JSON.stringify(param)}`

        }

        wx.reLaunch({

            url:url,

            fail(err) {

                console.log('reLaunch跳转出错',err)

            },

        })

    }

}

使用方法

在页面中引入封装的两个文件

import route from './../../utils/route.js'
import UtilRoute from './../../utils/UtilRoute.js'

只需将路由方法写入函数中调用即可,请看例子:

在list页面中接收参数

参数的传递,在navigateTo方法中使用JSON字符串方法处理过,在接收时需要对应处理获取

以上对参数的封装解决了第二个问题,对 navigateBack 的封装解决了第三个问题

功能-语音合成(tts)

1.申请账号

第三方平台:

1.讯飞:讯飞开放平台-以语音交互为核心的人工智能开放平台

2.百度:百度智能云-登录

2.生成音频文件

三方接入步骤:

1.申请平台账号后,需要新建应用,以获取相应的id和key参数

2.通过id、key和其它的参数,获取授权验证

3.调用相应语音合成的接口,将文本转化成音频文件

讯飞开发文档:讯飞开放平台文档中心

百度开发文档:百度AI开放平台-全球领先的人工智能服务平台-百度AI开放平台

百度语音合成接入demobaidu-video-demo.rar

3.音频文件播放

音频组件

<!--

    poster:音频封面图片

    name:歌名

    author:歌手

    src:音频地址

    controls:是否显示默认控件,也就是下面这个东东

    loop:是否循环播放

    id:标注唯一组件以this.audioCtx = wx.createAudioContext('myAudio')获取控制组件的对象。

    bindplay:播放时触发该事件

    bindpause:停止时触发该事件

    bindtimeupdate:时间改变时触发,该函数携带有参数detail={currentTime, duration}当前时间,持续播放时间

    bindended:播放结束时触发

    binderror;播放错误时调用,携带参数detail = {errMsg: MediaError.code}

 -->

<view class="page">

    <view class="page__bd">

        <audio poster="{{poster}}" name="{{name}}" author="{{author}}" src="{{src}}" id="myAudio" controls loop

               bindplay="funplay" bindpause="funpause" bindtimeupdate="funtimeupdate" bindended="funended"

               binderror="funerror"></audio>

        <button type="primary" bindtap="audioPlay">播放</button>

        <button type="primary" bindtap="audioPause">暂停</button>

        <button type="primary" bindtap="audio14">设置当前播放时间为14秒</button>

        <button type="primary" bindtap="audioStart">回到开头</button>

    </view>

</view>

注意:语音合成只支持纯文本的合成,不支持html,所以html的文本需要处理成存文本。处理方法见:字符串

// pages/video/video.js

Page({

    /**

     * 页面的初始数据

     */

    data: {

        poster: 'http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000',

        name: '此时此刻',

        author: '许巍',

        src: '',

    },

    onReady: function (e) {

        // 使用 wx.createAudioContext 获取 audio 上下文 context

        this.audioCtx = wx.createAudioContext('myAudio')

    },

    /**

     * 生命周期函数--监听页面加载

     */

    onLoad: function (options) {

        let that = this;

        // 百度语音合成接口

        wx.request({

            url: 'http://192.168.1.151:3000/baiduAI/speech',

            data: {

                text: '日光岩,是鼓浪屿每天第一缕阳光照到的地方,俗称""岩仔山"",别名""晃岩"",相传1641年,郑成功来到晃岩,看到这里的景色胜过日本的日光山,便把""晃""字拆开,称之为""日光岩""。日光岩游览区由日光岩和琴园两个部分组成。日光岩耸峙于鼓浪屿中部偏南,是由两块巨石一竖一横相倚而立,成为龙头山的顶峰,海拔92.7米...',

                spd: '6',

                pit: '3',

                vol: '8',

                per: '0'

            },

            method: 'POST',

            success(res) {

                let data = res.data;

                if (data.ret === 0) {

                    that.setData({

                        src: data.data.path + '?rnd=' new Date().getTime()

                    })

                else {

                    wx.showToast({

                        title: data.msg,

                    });

                }

            },

            fail(err) {

                console.log('err');

                console.log(err)

            }

        });

    },

    audioPlay: function () {

        this.audioCtx.play()

    },

    audioPause: function () {

        this.audioCtx.pause()

    },

    audio14: function () {

        this.audioCtx.seek(14)

    },

    audioStart: function () {

        this.audioCtx.seek(0)

    },

    funplay: function(){

        console.log("audio play");

    },

    funpause: function(){

        console.log("audio pause");

    },

    funtimeupdate: function(u){

        console.log(u.detail.currentTime);

        console.log(u.detail.duration);

    },

    funended: function(){

        console.log("audio end");

    },

    funerror: function(u){

        console.log(u.detail.errMsg);

    },

})

功能-语音录制、播放

录音API

wx.getRecorderManager()

获取全局唯一的录音管理器 RecorderManager

注:从基础库1.6.0开始,wx.stopRecord()和wx.startRecord()接口停止维护,全部使用wx.getRecorderManager代替进行操作

使用方法

在生命周期函数--监听页面加载onLoad中对API进行初始化,对录音的各项操作进行监听

示例代码

var that = this;

    this.recorderManager = wx.getRecorderManager();

    // 监听录音失败

    this.recorderManager.onError(function () {

      that.tip("录音失败!")

    });

    // 监听录音结束

    this.recorderManager.onStop(function (res) {

      that.setData({

        src: res.tempFilePath

      })

      console.log(res.tempFilePath)

      that.tip("录音完成!")

    });

    this.recorderManager.onPause(function() {

      // 监听录音暂停

      // 录音暂停事件的回调函数

    });

    this.recorderManager.onResume(function() {

      // 监听录音继续

      // 录音继续事件的回调函数

    });

    this.innerAudioContext = wx.createInnerAudioContext();

    // 监听录音播放失败

    this.innerAudioContext.onError((res) => {

      that.tip("播放录音失败!")

    })

录音开始事件

RecorderManager.start(Object object)

参数

属性

类型

默认值

必填

说明

durationnumber60000录音的时长,单位 ms,最大值 600000(10 分钟)
sampleRatenumber8000采样率,每种采样率有对应的编码码率范围有效值,设置不合法的采样率或编码码率会导致录音失败
numberOfChannelsnumber2录音通道数(1或2)
encodeBitRatenumber48000编码码率,8000的采样率对应的是16000~48000的编码码率
formatstringaac音频格式(仅支持 aac 和 mp3 格式)
frameSizenumber指定帧大小,单位 KB。传入 frameSize 后,每录制指定帧大小的内容后,会回调录制的文件内容,不指定则不会回调。暂仅支持 mp3 格式。
audioSourcestringauto指定录音的音频输入源,可通过 wx.getAvailableAudioSources() 获取当前可用的音频源

object.sampleRate 的合法值

说明

80008000 采样率
1102511025 采样率
1200012000 采样率
1600016000 采样率
2205022050 采样率
2400024000 采样率
3200032000 采样率
4410044100 采样率
4800048000 采样率

录音开始传参

// 自定义参数

const options = {

  duration: 10000,

  sampleRate: 44100,

  numberOfChannels: 1,

  encodeBitRate: 192000,

  format: 'aac',

  frameSize: 50

}

// 调用

this.recorderManager.start(options)

停止录音

recorderManager.stop()

在停止事件中直接对这个方法进行调用即可

/**

  * 停止录音

  */

 stopRecord: function () {

   this.recorderManager.stop()

 }

在结束录音时,会对事件进行监听,得到返回的录音文件的临时路径,利用这个路径可以进行录音的播放和上传

监听示例

this.recorderManager.onStop(function (res) {

    // 对录音临时路径进行处理

      that.setData({

        src: res.tempFilePath

      })

      console.log(res.tempFilePath)

      that.tip("录音完成!")

    });

在监听录音结束时,可以利用  wx.uploadFile  接口对音频进行上传操作

语音播放

需要使用到 wx.createInnerAudioContext  接口

简单示例代码

// 参考初始化录音接口,对音频播放接口进行初始化

this.innerAudioContext = wx.createInnerAudioContext();

this.innerAudioContext.onError((res) => {

    // 监听播放失败

    that.tip("播放录音失败!")

})

/**

   * 播放录音

   */

  playRecord: function () {

    var that = this;

    var src = this.data.src;

    // 判断录制音频是否存在

    if (src == '') {

      this.tip("请先录音!")

      return;

    }

    // 赋值录音文件地址,直接调取播放接口

    this.innerAudioContext.src = this.data.src;

    this.innerAudioContext.play()

  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值