91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

mpvue如何開發音頻類小程序

發布時間:2021-07-19 09:30:47 來源:億速云 閱讀:163 作者:小新 欄目:web開發

這篇文章主要為大家展示了“mpvue如何開發音頻類小程序”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“mpvue如何開發音頻類小程序”這篇文章吧。

這是我第一次開發小程序,開發的產品是音頻類的,在大佬的建議下采用了 mpvue ,一周時間把功能都做出來,由于不太熟悉mpvue和微信小程序,足足用了一周時間來改bug才出來一個能用的版本,在這里整理分享下我開發時遇到的一些問題和給出一些建議。

mpvue如何開發音頻類小程序

Linux 上開發小程序

在公司電腦裝了雙系統,日常用的是 Ubuntu 系統,Linux或Mac的開發環境對前端相對來說會友好一些。微信小程序官方的開發者工具只有 WindowsMac 版本,所以這就尷尬了。

不過還好,發現已經有大神在GitHub上做了Linux的支持,推薦給大家: Linux微信web開發者工具 。 根據教程安裝使用即可,使用時就用 ./bin/wxdt 命令打開。不過用了幾天后面覺得不太方便,就索性切回Windows系統用官方最新的版本了。

封裝wx.request為Promise

wx.request 用于發起http請求,但平時習慣了Promise的寫法,所以還是封裝一下這個方法為Promise的形式。 我看很多小程序會使用fly 這個庫。

但個人覺得發起請求不需要那么強大的功能,小程序本身就應該是一個輕量級的東西,引入一個庫可能會導致項目打包變大,可能讓小程序更卡,所以本著能自己寫就自己寫吧的心態,索性自己封裝一下算了。

src/utils ,新建一個 request.js :

const apiUrl = 'https://your server.com/api/'
const request = (apiName, reqData, isShowLoading = true) => {
 // 某些請求可能不需要顯示loading
 if (isShowLoading) {
 wx.showLoading({
  title: '正在努力加載中',
  mask: true
 })
 }

 return new Promise(function (resolve, reject) {
 wx.request({
  url: apiUrl + apiName,
  method: 'POST',
  data: reqData,
  header: {
  'content-type': 'application/json' // 默認值
  },
  success (res) {
  if (res.data.code === 0) {
   // 與后端約定code=0時才是正常的
   resolve(res)
  } else {
   reject(res)
  }
  },
  fail (err) {
  reject(err)
  },
  complete (res) {
  wx.hideLoading()
  }
 })
 })
}

export default request

當然這是個簡化版的,我實際項目中還會在初始化時加入一些 token 之類的參數,大家能看明白是這樣封裝成Promise的就可以啦。

使用vant-weapp

小程序已經支持了npm安裝,但不太會弄。還是按網上方法,將項目clone下來放進static目錄下。

git clone https://github.com/youzan/vant-weapp.git

然后將 vant-weappdist 目錄拷貝到項目的static目錄下(盡可能精簡,刪掉一些奇奇怪怪的如 .github 的東西,所以直接使用dist目錄),改名為 vant (也可以不改名)。全局使用時,可以在 app.json 引入:

 "usingComponents": {
 "van-button": "/static/vant/button/index",
 "van-field": "/static/vant/field/index"
 },

注意:需要打開微信開發者工具中的ES6轉ES5功能

一開始以為使用起來和web端的沒啥差別,但沒想到那么麻煩。比如:在vue中是可以使用 v-model 的,但在mpvue中的小程序中不能使用,只能

<van-field :value="password" type="password" @change="pwdChange" input-class="myClass" />

而且不能隨意靈活添加class修改組件的樣式,需要vant組件支持提供外部樣式才可修改,比如上面的 van-field 是通過 input-class 來添加樣式控制的,很不方便。而且某些內部樣式由于沒有外部樣式表,根本改不了。

綜上: 在微信小程序使用第三方組件庫不太方便,樣式修改比較麻煩,如果產品是有UI設計時, 盡量不使用 ,有時候自己實現樣式可能更快,而且項目體積更小。

使用vuex

mpvue官方的快速模板中是將vuex放在 counter 這個page目錄下,可能習慣了vue官方寫法的很多同學(包括我)不太喜歡,所以最好就改為vuex官方的寫法。

在src目錄下建一個 store 的文件夾,分別建以下文件:

mpvue如何開發音頻類小程序

項目不太復雜時不建議使用modules,使用起來比較麻煩。

貼一下 index.js 的代碼,其他的 actions.js , getters.js 按官方的寫法就好啦。

import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'
import createLogger from 'vuex/dist/logger'

Vue.use(Vuex)

const debug = process.env.NODE_ENV !== 'production'

export default new Vuex.Store({
 actions,
 getters,
 state,
 mutations,
 strict: debug,
 plugins: debug ? [createLogger()] : []
})

vuex/dist/logger 是vuex在開發環境可以自動打印日志的工具,debug比較方便,建議使用。 然后在 src/main.js 引入:

import Vue from 'vue'
import App from './App'
import store from '@/store'

Vue.config.productionTip = false
App.mpType = 'app'

Vue.prototype.$store = store

const app = new Vue({
 store
})
app.$mount()

這樣就可以在項目中正常使用啦,完全支持 mapState , mapActions , mapGetters 的寫法,比如在 pages/index/index.vue 中使用:

<script>
import { mapState, mapActions } from 'vuex'
export default {
 computed: {
 ...mapState(['myAudio'])
 },
 methods: {
 ...mapActions(['myActions'])
 },
 created () {
 this.myActions() //調用vuex中的方法
 }
}
</script>

踩坑指南

其實大多數坑可能是mpvue的,很多情況也是自己不熟悉小程序生命周期導致的一些奇奇怪怪的bug。

mpvue是支持小程序原生組件的

mpvue會將 div 編譯為小程序中的 view 。一開始我不了解,以為用了mpvue后就不能使用小程序原生支持的組件了,比如 swiper , scroll-view 等,小程序是支持的,可以放心使用哈哈。

npm run build后樣式丟失

本來在開發環境正常的,然后準備發版 npm run build 后發現樣式丟失了。然后重新 npm start 排查問題,樣式還是丟失的。內心此時是mmp的:npm run build丟失就算了,我沒改什么東西重新npm start后為什么還是丟失,之前還是正常的呀?

剛開始懷疑是緩存什么的問題,刪掉的dist目錄,重啟開發者工具,甚至重啟電腦都試了一下,這是我遇到的超級詭異的問題之一。

冷靜下來想到:之前的版本是正常的,一定是新版本引入了什么導致了打包樣式的丟失。于是回滾版本一個個build排查問題,最后找到了原因: 在一個page中引入了其他page,即在頁面中import另一個頁面。

在我這里的具體例子是:我在 pages/index/index.vue 中想做底部共用一個tabbar,頁面根據tabbar的值來顯示對應的子級頁面: pages/page1/index.vuepages/page2/index.vue

所以我將這兩個頁面當做子組件來引入了: import Page1 from '@/pages/page1' ,一開始沒有問題,等重啟項目,或者build后就發現樣式丟失了。

這可能是mpvue打包機制的一個限制,即 頁面不能將另一個頁面當子組件來引用 ,否則會導致樣式丟失。

背景音頻的src無法讀取

項目中希望用戶退出小程序后依然能播放音頻,所以用到了背景音頻的api: wx.getBackgroundAudioManager()。

this.audio = wx.getBackgroundAudioManager()
this.audio.src = 'http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E061FF02C31F716658E5C81F5594D561F2E88B854E81CAAB7806D5E4F103E55D33C16F3FAC506D1AB172DE8600B37E43FAD&fromtag=46' 
this.audio.title = '此時此刻' //注意必填
this.audio.epname = '此時此刻'
this.audio.singer = '許巍'
this.audio.coverImgUrl = 'http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000'

titlesrc 賦值后會直接播放音頻,后面的幾個屬性建議也填上,因為播放背景音頻時微信是有個界面需要封面圖和歌手名稱等的。

如果想要獲取當前正在播放的音頻src,本來以為通過 this.audio.src 來獲取就可以了但是有bug。

在開發者工具中是可以正常獲取的,即開發時是沒問題的,但在真機上返回的是 undefined ,因此不能用 this.audio.src 來獲取當前播放的音頻url,得用一個變量來存這個數據。

直接使用音頻的currentTime可能渲染不及時

currentTime用于顯示當前的播放進度,但我用在子組件中時經常更新不及時,打印是正常的,但試圖渲染不及時,有時候需要點擊一下才能重新渲染,這可能是mpvue使用時才會遇到。

所以建議還是項目自身維護一套背景音頻的變量比較好一點,比如放在 vuex 中。監聽 BackgroundAudioManager.onTimeUpdate() 方法每次賦值到自身維護的變量中。

音頻的onCanplay方法不一定每個音頻都會觸發

一開始我監聽在 onCanplay 方法,將音頻的時長信息 duration 賦值到vuex中存起來,但發現 onCanplay 有時候是不會觸發的,比如重新賦值src播放下一首時,很尷尬。

所以不要太依賴onCanplay這個方法,還好目前直接使用 audio.duration 好像不會出現像上面的 currentTime 渲染不及時的問題,所以就這樣用著先。

音頻播放結束,即onStop后,不能再通過audio.play()的方法重新播放,得重新賦值src

正常來說,音頻播放結束后,音頻的src是不變的,再次 play() 應該是可以的。但在小程序中偏偏不行,得重新賦值src才能重新播放,這應該是小程序的一個bug。。。

所以需要判斷一下 暫停停止 的情況,用不同的辦法播放。正常來說,音頻暫停時 currentTime 是不為0的,而結束時 currentTime 會為0。

所以可以通過 currentTime (最好是自己維護的變量)來判斷暫停和停止的情況: 如果currentTime不為0,表示是暫停的情況,可以用 play() ,如果小于等于0,則重新賦值src播放 :

if (currentTime) {
 this.audio.play()
} else {
 this.audio.src = 'xx.mp3'
}

mpvue不支持直接在template上直接綁定函數

這個是mpvue文檔上有寫的,不過一開始并不是很理解,也踩坑了,所以在這里提一下,避免不知道的同學踩坑找半天。

<template>
 <div v-for="(item, index) in list" :key="index">{{ formatItem(item) }}</div>
</template>
 
<script>
export default {
 data () {
 return{
  list: [1, 2, 3]
 }
 },
 methods: {
 formatItem (item) {
  return `我是${item}`
 }
 }
}
</script>

上面的代碼應該是日常vue中比較常用的,就是將數據傳參給方法做一些處理,這個在mpvue中是不支持的,會被編譯成一個空字符串。

小程序中可放心使用css3的一些特性

比如高斯模糊

filter: blur(50px);

如果要使用動畫,盡量用 css 動畫代替 wx.createAnimation

在實際使用時, wx.createAnimation 做動畫其實很卡,性能很差,所以在需要使用動畫時,建議盡量使用css做動畫。

在小程序中是支持css動畫的, transition , animation , @keyframes 這些特性都支持。

比如做一個div一直旋轉的動畫,大家可以對比一下兩個版本:

wx.createAnimation 版本

原理:通過setInterval()不斷更新div的旋轉位置

<template>
 <div class="cover" :animation="animationData"></div>
</template>

<script>
export default {
 data () {
 return {
  animationData: '',
  animation: '',
  rotateCount: 0,
  timer: ''
 }
 },
 components: {

 },
 methods: {
  startRotate () {
  this.timer = setInterval(() => {
   this.rotateAni(++this.rotateCount)
  }, 100)
  },
  rotateAni (n) {
  if (!this.animation) {
   return
  }
  // 每100毫秒旋轉10度
  this.animation.rotate(10 * n).step()
  this.animationData = this.animation.export()
  }
 },
 onShow () {
  // 頁面從隱藏到顯示時才執行
  if (!this.animation) {
  this.animation = wx.createAnimation()
  this.startRotate()
  }
 },
 onReady () {
  // 第一次初始化時會執行
  if (!this.animation) {
  this.animation = wx.createAnimation()
  this.starRotate()
  }
 },
 onHide () {
 // 頁面隱藏時會執行,避免頻繁的setData操作,將定時器停掉
 this.timer && clearInterval(this.timer)
 },
 beforeDestroy () {
 // 頁面卸載,也停掉定時器
 this.timer && clearInterval(this.timer)
 }
}
</script>

<style scoped lang="scss">
 .cover {
 left: 20px;
 bottom: 70px;
 border-radius: 50%;
 background: #fff;
 position: absolute;
 width: 50px;
 height: 50px;
 background: rgba(0, 0, 0, 0.2);
 box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.2);
 border: 1px solid rgba(255, 255, 255, 0.5);
 overflow: hidden;
 z-index: 10000;
 }
</style>

使用css的 @keyframes 做旋轉動畫

<template>
 <div class="cover" :></div>
</template>

<script>
export default {
}
</script>

<style scoped lang="scss">
 // 定義一個動畫名為 rotate
 @keyframes rotate {
 0%,
 100% {
  transform: rotate(0deg);
 }
 100% {
  transform: rotate(360deg);
 }
 }
 .cover {
 left: 20px;
 bottom: 70px;
 border-radius: 50%;
 background: #fff;
 position: absolute;
 width: 50px;
 height: 50px;
 background: rgba(0, 0, 0, 0.2);
 box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.2);
 border: 1px solid rgba(255, 255, 255, 0.5);
 overflow: hidden;
 z-index: 10000;
 // 使用動畫
 animation: rotate 4s linear infinite;
 }
</style>

用js寫的動畫需要控制好setInterval的間隔時間和旋轉角度,比較難調。而用css寫動畫很簡單,性能比js好,代碼量也很少。

使用css動畫時建議開啟硬件加速

為了動畫更流暢,想盡辦法做優化,雖然不知道有沒效果,反正用了再說[手動滑稽]。

可以用will-change和transform: translate3d(0,0,0) 開啟硬件加速。我也不太會用,具體用法大家自行百度Google。

will-change: auto;
transform: translate3d(0, 0, 0);

iPhoneX需要底部導航條預留34px(68rpx)的高度

由于小程序中不能設置 viewport-fit=cover ,所以也就沒有web中的安全區域說法,目前主流的做法是通過 wx.getSystemInfoSync() 判斷是否是ipx,若是則給頁面底部撐高34px。

const res = wx.getSystemInfoSync()
if (res.model.indexOf('iPhone X') >= 0) {
 this.isIpx = true
}

注意是用 res.model.indexOf('iPhone X') ,在開發者工具的iPhone X中,model是全等于 iPhone X 的,但在真機中往往拿到的值是 iPhone X GZxxx ,即后面可能會帶一串東西,所以用 indexOf 才是比較穩的,而且對 iPhone XR 等機型也適用。

由于還有其他安卓機的全面屏,不太可能一一判斷,而且某些安卓全面屏是沒有用iPhone底部的工具條的(不存在沖突的情況),所以我們只判斷iPhone X的情況就可以了,其他全面屏就不需要給底部預留了。

至于全面屏布局的適配,需要用 flex 布局或者獲取屏幕寬高來慢慢調了,建議最好用flex布局自適應處理。

for循環中的子組件click事件無法觸發

Page -> 父組件 -> 子組件 ,在子組件click后 $emit 一個事件出來,發現無法觸發。

這個bug一開始沒有出現,但偶然 npm run build 出現的,然后排查原因,后面即使回滾所有版本再npm start也還會出現。好像不觸發則已,一發就不可收拾,這又是一個大坑,搜issue和加群問人,當晚下班回家研究到1點多都沒有解決。

第二天繼續研究,感覺可能是框架的原因,最后嘗試升級一下mpvue版本,沒想到就正常了。直接使用quick-strat項目的 mpvue 版本是 2.0.0, mpvuempvue-template-compiler 升級到最新 2.0.6 就解決了。

事后查看mpvue版本記錄,果然是框架本身原因,并且找到了 issue 。

npm run build后代碼報錯,再build一次可能報另一些錯

解決: 沒找到原因,可能是引入vant導致的,打包時丟失了部分文件。多build幾次,或者重啟下小程序開發者工具就正常了。

mpvue中created() 鉤子會在頁面初始化時全部一起觸發,盡量不要用 小程序生命周期的理解

進入已銷毀的page組件時依次觸發: onLoad,onShow,onReady,beforeMount,mounted

第一次進入已銷毀的子組件時依次觸發: onLoad,onReady,beforeMount,mounted

第二次進入已銷毀的子組件時依次觸發: onLoad,onShow,onReady

再次進入 未被銷毀的page組件、子組件時只觸發: onShow

mpvue文檔中建議盡量不要使用小程序的生命周期,這個應該是為了讓項目更好地適應支付寶小程序和頭條小程序等,所以才這樣建議大家盡量不要使用某一個小程序自身的api。

如果你們的小程序只是微信小程序(不考慮兼容其他平臺小程序),我建議 直接用小程序的生命周期 ,而不要用mpvue的生命周期,坑太多了。比如mpvue的created周期,初始化時所有的page都會執行,所以created這個周期是不能用了。

onUnload不觸發

小程序中與平常web開發不同的是,它的頁面會被緩存。舉個例子:

  1. page1 跳轉到 page2 ,再從 page2 返回 page1 ,此時的 page1 還沒銷毀,不會觸發 onLoad 再重新渲染,而是直接使用之前的數據。從性能上來說,單純的返回不應該再請求api獲取數據重新渲染,這是對的,符合我們的預期。

  2. 而有時候,從 page2 返回 page1 時,我們希望 page1 是重新獲取數據渲染的。比如在 page2 做了一個退出登錄的操作,此時再返回 page1 時,還是會看到之前的數據。實際上我們的預期是:由于已經退出登錄了, page1 的數據應該被銷毀了。

在平常的web開發中,遇到上面的問題,我們可能是不管緩存,每次返回 page1 都再次請求api渲染最新的數據,犧牲掉部分性能從而保證邏輯的正確性。

在mpvue中我也嘗試這樣干了:想在 page1onUnload() 生命周期中銷毀數據,但是沒有成功。即使在 page2 退出登錄時,采用 wx.reLaunch() 重新刷一遍, page1onUnload() 生命周期也沒有執行。所以 onUnload() 是有可能不執行的,建議慎用。

最后還是得想辦法做到 page2 控制 page1 的數據銷毀或保留 。想到這里, vuex 就不自覺浮現在眼前了,如果page1的數據是通過vuex來控制的,那么我在page2就可以用vuex來靈活管理其他頁面的數據了。

如果page2做退出登錄操作時,就讓page1的數據銷毀,如果是不退出登錄正常返回,page1的數據還是正常,做到靈活控制。

個人平時web開發很少用 vuex ,因為項目比較簡單不用那么復雜的全局數據傳遞。但在小程序中,建議全局使用 vuex 來控制所有數據(當然是得根據需求來用)。

總結

第一次開發小程序就直接上了mpvue,可能有些坑已經很多同學總結過了,有些坑可能是不熟悉而導致的,但自己沒有去踩過一遍可能不夠深刻。

有兩種坑會比較難啃:

框架本身的問題,如mpvue2.0.0出現的子組件無法觸發事件的問題。 開發者工具和真機運行環境不一致導致的坑。

遇到真機和開發者工具不一致的情況,可按以下步驟排查:

  • 有可能是緩存,可以殺掉之前的版本再跑起來

  • 手機微信版本太低,可能api不支持,用wx.canIUse打印一下

  • 手機端某些屬性不支持讀取,比如上面的this.audio.src,可以在真機打印調試一下

  • 代碼在手機端運行有報錯,可以在手機端開啟調試,看一下log

  • 微信設計上的坑,百度下是否有相關的案例和解決辦法

而遇到mpvue框架的問題可以:

  • 去搜一下mpvue的issue看有沒相關解決辦法

  • 盡量使用最新版本的框架,可能某些問題已經修復了的。實在解決不了的,建議想辦法繞過,換一種方法來實現。

以上是“mpvue如何開發音頻類小程序”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

三门县| 科技| 措勤县| 九台市| 浦城县| 桓台县| 扶沟县| 沧州市| 嘉峪关市| 新兴县| 陈巴尔虎旗| 鄂托克前旗| 论坛| 石楼县| 临沭县| 河曲县| 曲阜市| 盘锦市| 老河口市| 西和县| 无为县| 志丹县| 庆元县| 修武县| 龙泉市| 广灵县| 灵丘县| 安多县| 夹江县| 濮阳县| 天气| 黑水县| 永嘉县| 新绛县| 赤水市| 驻马店市| 南宫市| 惠来县| 东阳市| 宣威市| 崇文区|