标签 微信小程序 下的文章

我们在使用微信小程序开发工具进行测试的时候发现使用chooseVideo或者是chooseMedia的时候,会出现"chooseVideo:fail DEMUXER_ERROR_NO_SUPPORTED_STREAMS: FFmpegDemuxer: no supported streams"这样的错误,看大家在社区已经反映过了,官方给出的答复是正在修复,所以现在也没有比较好的解决方案。我们可以使用老版本进行测试,下面小编就给大家提供下小编使用的版本,这个版本的缺陷就是,在MacOS Big Sur出现频繁崩溃的问题,也不是十分好用。

系统:MacOS Big Sur
工具版本: 微信开发者工具1.03.2011120
问题: chooseVideo或者是chooseMedia,出现"chooseVideo:fail DEMUXER_ERROR_NO_SUPPORTED_STREAMS: FFmpegDemuxer: no supported streams"

下载地址: https://developers.weixin.qq.com/community/develop/doc/0000c4f9440410caa11ab51cd5b801

在微信小程序里面如果想引用地图,那么可以直接使用map组件,详细的使用方法呢大家可以看下小程序的开发文档,小编这里主要说下小编遇到的问题。
你可以自定义主题,搜索腾讯地图,登录后,选择左侧的自定义样式,然后再输入小程序的APPID,这样你就可以获取到KEY值了。然后指定自定义属性:subkey就可以了。
另外小编再说下汽包的使用吧。这就用到了markers属性,markers是一个数组的形式,你可以看下文档,设置相对应的属性。另外呢,气泡有两种模式:callout和label。callout当用户点击的时候显示标注的content内容,label是默认直接显示的,用法两者相同。
使用案例

 markers = [{
        '_id': 1,
        'name': '',
        'iconPath': '',
        'width': 20,
        'height': 20,
        'longitude': 111.1111,
        'latitude': 32.1111,
        'callout': {    // 可以是label
            'content': '小宁博客',
            'borderColor': '#f4f4f4',
            'color': '#ffffff',
            'bgColor': '#000000',
            'borderRadius': 10,
            'padding': 10
        }
        ....
   ]

小编今天升级了微信小程序开发工具,发现小程序里面出来了一个警告,显示无效的 appJSON["navigateToMiniProgramAppIdList"]。之前一直没有这个问题的。后来通过查资料发现。

从2020年4月24日起,使用跳转其他小程序功能将无需在全局配置中声明跳转名单,调用此接口时将不再校验所跳转的 AppID 是否在 navigateToMiniProgramAppIdList 中。
从2020年4月24日起,跳转其他小程序将不再受数量限制,使用此功能时请注意遵守运营规范。

所以说现在不需要这个配置项了,直接从app.json里面删除就可以了。

微信小程序swiper组件中当数据少于display-multiple-items设置的数,就会出现这个不显示这个问题在社区看到在2019年的8月份已经有人提出了,官方说的是:目前可以通过追加空的swiper-item解决,我们也在想办法优化这块能力。这显然不是我们想要的结果,空的swiper-item,就会显示空白。
首先我们来分析下问题:当swiper组件中当数据少于display-multiple-items设置的数量的时候才会出现这样的问题,我们假设我们要显示3个。

display-multiple-items设置的数swiper组件中当数据显示个数是否正常
343
333
222
111
000

通过这个表格我们就可以很清楚的发现,当swiper组件中当数据数大于或则等于display-multiple-items设置的数的时候,就会显示正常。那么我们就可以动态的设计display-multiple-items的数量,如果swiper组件中当数据数大于或则等于display-multiple-items设置的数的时候,我们就显示我们要限定的数,否则就显示display-multiple-items的数量。这样我们就可以完美的绕开这个问题了。同时宽度(或者高度)我们也采用这种的方式来进行动态的设置就可以了。
示例代码:

<swiper style="width: 90%; height: {{datas.length>2?'330':datas.length*110}}rpx; vertical="true" autoplay="true" circular="true" interval="2000" display-multiple-items="{{datas.length>2?3:datas.length}}">
    <block wx:for="{{datas}}">
        <swiper-item>
                <image src="{{item.avatar}}" style="width: 70rpx; height: 70rpx;min-width: 70rpx;min-height: 70rpx;" />
        </swiper-item>
    </block>
</swiper>

微信小程序中swiper组件禁止用户上下滑动这个实现起来比较的简单,我们通过手册会发现,该组件的swiper-item里面上下滑动会执行函数catchtouchmove,所以我们可以通过控制这个函数来实现

< swiper-item catchtouchmove=“stopTouchMove” >< swiper-item >
stopTouchMove: function() {
    return false;
}

这种方法可以阻止手动滑动,但是带来的影响是:页面不能滑动了。这是由于在你上下滑动的时候,仍然会执行滑动的这个动作,但是触发的函数没有进行任何的操作,如果我们想让页面也滑动,我们采用下面的方法。

给这个区域一个模板压在上面,但是该组件本身就应用了定位,那么我们可以采用,前置方法:

<swiper class="swiper-disabled">
    ......               
</swiper>
.swiper-disabled {
    position: relative;
}

.swiper-disabled::after {
    position: absolute;
    content: '';
    top: 0;
    left: 0;
    width: 100%;
}

这样我们就解决了这个问题了。

微信小程序现在可以开通直播功能,只要符合资质的都可以开通直播。开通该功能后,我们只需要按照文档里面说明的方式开发就好了。
首先我们引入【直播组件】 live-player-plugin
分为两种方式引入,一种是在主包中引入,另一种是在分包中引入。因为直播组件不计入代码包体积,所以小编建议大家在主包引入,而且还有些功能只能在主包中使用,这个也是看大家的需求。
引入方式,在app.json里面引入,json文件里面不能写注释,大家在引入的时候记得把注释删除掉:

  • 主包引入

    "plugins": {
          "live-player-plugin": {
              "version": "1.0.5", // 注意填写该直播组件最新版本号,微信开发者工具调试时可获取最新版本号(复制时请去掉注释)小编在开发的时候版本是1.0.5
              "provider": "wx2b03c6e691cd7370" // 必须填该直播组件appid,该示例值即为直播组件appid(复制时请去掉注释)
          }
      }
  • 分包引入

    "subpackages": [
          {
              "plugins": {
                  "live-player-plugin": {
                      "version": "1.0.5", // 注意该直播组件最新版本号,微信开发者工具调试时可获取最新版本号(复制时请去掉注释)
                      "provider": "wx2b03c6e691cd7370" // 必须填该直播组件appid,该示例值即为直播组件appid(复制时请去掉注释)
                  }
              }
          }
      ]

接下来我们就要进入直播间了,不需要我们写直播的界面,只需要跳转到直播组件就可以了。分享官方也给封装好了,只需要拿来使用就可以了,跳转方式也有两种,房间号在你创建完直播间的时候就有了。

  • 直接通过navigator进行跳转

    let roomId = [直播房间id] // 房间号
      let customParams = { path: 'pages/index/index', pid: 1 } // 开发者在直播间页面路径上携带自定义参数(如示例中的path和pid参数),后续可以在分享卡片链接和跳转至商详页时获取,详见【获取自定义参数】、【直播间到商详页面携带参数】章节
      this.setData({
          roomId,
          customParams: encodeURIComponent(JSON.stringify(customParams))
      })
      <navigator url="plugin-private://wx2b03c6e691cd7370/pages/live-player-plugin?room_id={{roomId}}&custom_params={{customParams}}"></navigator>
      // 其中wx2b03c6e691cd7370是直播组件appid不能修改
  • js中跳转

    let roomId = [直播房间id] // 房间号
      let customParams = { path: 'pages/index/index', pid: 1 } // 开发者在直播间页面路径上携带自定义参数(如示例中的path和pid参数),后续可以在分享卡片链接和跳转至商详页时获取,详见【获取自定义参数】、【直播间到商详页面携带参数】章节
      wx.navigateTo({
          url: `plugin-private://wx2b03c6e691cd7370/pages/live-player-plugin?room_id=${roomId}&custom_params=${encodeURIComponent(JSON.stringify(customParams))}`
      })
      // 其中wx2b03c6e691cd7370是直播组件appid不能修改

另外在说一下获取直播间列表的方法、

【获取直播房间列表】接口,仅供后台调用
接口规则:该接口仅供商家后台调用,调用限额 500 次/天,建议开发者自己做缓存(此接口与下面【获取回放视频】接口共用 500 次/天限制,请合理分配调用频次)。

请求URL: http://api.weixin.qq.com/wxa/business/getliveinfo?access_token=

请求方式: POST

请求示例:

  • Request
    {
        "start": 0, // 起始拉取房间,start = 0 表示从第 1 个房间开始拉取
        "limit": 10 // 每次拉取的个数上限,不要设置过大,建议 100 以内
    }

Response(官方文档可能有问题,anchor_img这个没返回,返回的是share_img)

    {
        "errcode": 0, // errcode = 0 代表成功;errcode = 1 代表未创建直播房间
        "errmsg": "ok",
        "room_info": [{
        "name": "直播房间名",
        "roomid": 1,
        "cover_img": "http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/Rl1RuuhdstSfZa8EEljedAYcbtX3Ejpdl2et1tPAQ37bdicnxoVialDLCKKDcPBy8Iic0kCiaiaalXg3EbpNKoicrweQ\/0?wx_fmt=jpeg",
        "live_status": 101,
        "start_time": 1568128900,
        "end_time": 1568131200,
        "anchor_name": "李四",
        "anchor_img": "http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/Rl1RuuhdstSfZa8EEljedAYcbtX3Ejpdlp0sf9YTorOzUbGF9Eib6ic54k9fX0xreAIt35HCeiakO04yCwymoKTjw\/0?wx_fmt=jpeg",
        "goods": [          
            {
                "cover_img": "http://mmbiz.qpic.cn/mmbiz_png/FVribAGdErI2PmyST9ZM0JLbNM48I7TH2FlrwYOlnYqGaej8qKubG1EvK0QIkkwqvicrYTzVtjKmSZSeY5ianc3mw/0?wx_fmt=png",
                "url": "pages/index/index.html",
                "price": 1100,
                "name": "fdgfgf"
            }
        ],
        "total": 1
    }

常用的就这些了,要是有需要小编说明的,欢迎在下方留言。
微信小程序开通直播功能.jpeg

微信小程序获取用户收货地址,这个功能在我们开发商城的时候,经常会用到,所以微信小程序专门提供了API,我们只需要直接调用就可以了。
实现代码:

getAddress: function() {
        let that = this;
        wx.chooseAddress({
            success(res) {
                console.error(res)
                console.log(res.userName)//收货人姓名
                console.log(res.postalCode)//邮编
                console.log(res.provinceName)//国标收货地址第一级地址
                console.log(res.cityName)//国标收货地址第二级地址
                console.log(res.countyName)//国标收货地址第三级地址
                console.log(res.detailInfo)//详细收货地址信息
                console.log(res.nationalCode)//收货地址国家码
                console.log(res.telNumber)//收货人手机号码
            }
        })
    },

实现效果:
收货地址.png
你只要对你自己的内容进行赋值就可以了。

微信小程序获取用户收货地址.jpeg

在微信小程序里面,页面基本上都是一个栈的数据结构,当我们使用wx.navigateto,打开一个新的页面的时候,这时候就会在栈顶显示这个页面,当我们使用wx.navigateBack() 返回上个页面的时候,就是把当前的页面pop出去。小编之前用过RN,当时采用的是回调函数来实现的,其实在小程序里面不需要这么麻烦,我们可以直接拿到页面栈,然后给上个页面直接赋值就行。
操作方法:

  1. 在当前页面执行:

    let pages = getCurrentPages(); // 拿到页面栈
    let prevPage = pages[pages.length - 2]; // 拿到上个页面,-1是当前页面
    prevPage.setData({ // 赋值
     addressid: e.currentTarget.dataset.addressid
    })
    wx.navigateBack({ // 返回
     delta: 1
    })
  2. 上一个页面:

    // 获取值并进行赋值(一般小编是写在onShow里面)
    this.setData({
    addressid: currPage.__data__.addressid || null
    })

    微信小程序wx.navigateBack() 携带参数返回.png

微信小程序的抽红包组件,小编一共是做了两种,第一种呢用了很长时间了,可能是时间长了,觉得不是那么霸气了,就重新又制作了一个,第一个当时使用了大量的图片,这也导致了加载的时候很慢,这里面的主要样式还是参考的别人的代码,总而言之效果还是不错的,不过现在呢,小编又自己写了个抽红包的组件,这回看上去比较好看了,首先我们先看下2.0代码吧。因为是放在具体项目里面的,有些细节性的东西大家可以改改:
首先是wxml,大部分的样式也写在了这里面:

<view style="position: fixed; top: 0; left: 0; display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; height: 100vh; z-index: 100000000000000000000; background: rgba(0, 0, 0, 0.4);">
    <view class="{{open ? 'red-packet-open' : ''}}" style="background: #ff3d32; border-radius: 30rpx; border-bottom-right-radius: 100% 120px; border-bottom-left-radius: 100% 120px; box-shadow: 0px 3px 5px 1px #e92c27; width: 590rpx; height: 700rpx; position: absolute; top: 80rpx; z-index: 101;">
        <view wx:if="{{name}}" style="color: #F5B37B; text-align: center; font-size: 40rpx; padding-top:100rpx;">{{name}}的红包</view>
        <view wx:if="{{text}}" style="color: #F5B37B; text-align: center; font-size: 30rpx; padding-top:60rpx;">{{text}}</view>
        <view style="position: absolute; bottom: -80rpx; left: 220rpx; background: #E8bF7B; width: 150rpx; height: 150rpx; line-height: 150rpx; text-align: center; border-radius: 75rpx; font-size: 60rpx;" bindtap="handleOpen">抽</view>
    </view>
    <view class="{{open ? 'red-packet-open' : ''}}" style="background: #ff3328; border-radius: 30rpx; border-top-right-radius: -120px; border-top-left-radius: -120px; width: 590rpx; height: 464rpx; position: absolute; top: 500rpx; z-index: 100;"></view>
    <view style="width: 590rpx; height: 883rpx; position: absolute; top: 80rpx; z-index: 90; background: #FFFFFF; border-radius: 30rpx;">
        <view style="height: 260rpx; border-radius: 30rpx; border-bottom-right-radius: 100% 120px; border-bottom-left-radius: 100% 120px; background: #ff3d32; display: flex; flex-direction: column; justify-content: center; align-items: center;text-align: center;">
            <image mode="aspectFill" src="{{user?user.avatar : ''}}" style="width: 130rpx; height: 130rpx; min-width: 130rpx; min-height: 130rpx; border-radius: 65rpx; position: absolute; top: 180rpx;" />
            <view style="position: absolute; top: 0; right: 20rpx; color: #FFFFFF; font-size: 56rpx;" bind:tap="close">X</view>
        </view>
        <view style="display: flex; flex-direction: column; justify-content: center; align-items: center;text-align: center; font-size: 26rpx; margin: 60rpx;">
            <text style="color: #f33035; font-size: 40rpx;">{{title}}</text>
            <text style="padding: 10rpx; color: #f33035; font-size: 50rpx;">{{msg}}</text>
            <view style="text-align: center; font-size: 30rpx; margin: 20rpx;">{{tips}}</view>
            <view wx:if="{{balance}}" bind:tap="toBalance" style="text-align: center; font-size: 30rpx; margin: 20rpx; color: #f33035; padding-top: 60rpx;"><text wx:if="{{balance_name}}">{{balance_name}}</text>余额:{{balance}}>>
            </view>
        </view>
    </view>
</view>

在wxss里面实现了一个动画:

.red-packet-open {
    animation: open-up 0.2s ease-in-out 0.2s 1 normal;
    animation-fill-mode: forwards;
    display: none;
}

在js里面就是相关的逻辑了

const audio = wx.createInnerAudioContext()
audio.src = 'https://audiosrc.shangpo.net/sources/coin.mp3'
let g = getApp().globalData;

Component({
    properties: {
        title: {
            type: String,
            value: null
        },
        msg: {
            type: String,
            value: null
        },
        tips: {
            type: String,
            value: null
        },
        bind: {
            type: Boolean,
            value: true,
        },
        open: {
            type: Boolean,
            value: false
        },
        amount_ui: {
            type: String,
            value: null
        },
        name: {
            type: String,
            value: null
        },
        text: {
            type: String,
            value: null
        },
        user: {
            type: Object,
            value: g.user
        }, 
        balance: {
            type: String,
            value: null
        },
        balance_name: {
            type: String,
            value: null
        }
    },
    data: {

    },
    methods: {
        handleOpen() {
            var that = this
            if (that.data.bind) {
                that.setData({
                    title: that.data.title,
                    msg: that.data.msg,
                    bind: false,
                    // 以下两项为测试页面使用
                    // tips: that.data.tips,
                    // open: true,
                })
                audio.play()
                this.triggerEvent('choujiang', {})
            }
        },
        close() {
            this.triggerEvent('close_redpacket', {})
        },
        toBalance(){
            this.triggerEvent('toBalance', {})
        }
    }
})

1.0版本的基本上就是样式上的不一样,小编在这里就不列出来了,有需要的可以单独联系小编。