mpvue 是什么
1、一套定位于開發小程序的前端開發框架,核心目標是提高開發效率,增強開發體驗;
2、框架提供了完整的Vue.js 開發體驗,開發者編寫Vue.js代碼,mpvue將其解析轉換為小程序并確保其正確運行;
3、框架還通過 vue-cli 工具向開發者提供 quick start 示例代碼,開發者只需要執行一條簡單命令,即可獲得運行的項目;
小程序開發階段面臨的主要問題
1、組件化機制不夠完善
2、代碼多端復用能力欠缺
3、小程序框架和團隊技術棧無法有機結合
4、小程序學習成本不夠低
使用Vue.js 開發小程序,帶來如下開發效率提升
1、H5代碼可以通過最小修改復用到小程序;
2、使用Vue.js 組件機制開發小程序,可實現小程序和H5組件復用;
3、技術棧統一后小程序學習成本降低,開發者從H5 轉換到小程序不需要更多學習;
4、Vue.js 代碼可以讓所有前端直接參與開發維護
Vue.js 與 小程序 的聯系
1、一致的工作原理:都是典型的邏輯視圖層框架,邏輯層和視圖層之間的工作方式為:數據變更驅動視圖更新;視圖交互觸發事件,事件響應函數修改數據再次觸發視圖更新。
mpVue 實現原理

本文是對CPASS項目的技術要點和所踩的坑做一些總結。
項目
一個提供移動辦公場地的小程序平臺。
使用美團mpvue框架, mpvue:1.0.13, mpvue-loader:1.0.15
靜態資源(除了tabbar圖標)放在阿里云oss

組件(頁面)間通信
四種方式:
這里說一下比較少用的第三種通信方式。Bus應用于非父子組件通信,利用$emit,$on,$off分別來分發、監聽、取消監聽。
第一步:在mixins(混合)建一個文件event-bus.js
import Vue from 'vue';export default new Vue();
第二步:在需要分發的組件中引入event-bus,再傳遞分發事件
import Bus from '@/mixins/event-bus'// 需要傳遞給兄弟組件的值let params = { ***}Bus.$emit('getParams', params)第三步:在需要監聽的組件中引入event-bus,在created周期去監聽事件(小程序周期監聽無效),在 beforeDestroy 周期取消監聽事件
import Bus from '@/mixins/event-bus'created () { // 監聽事件 Bus.$on('getParams', params => { // to do something })},beforeDestroy () { // 清除監聽 Bus.$off('getParams');}swiper選項卡 + 無限加載
利用微信官方提供的swiper封裝一個無限數據加載的swiperTab選項卡。

空態下:

技術難點:
swiper需要設置固定高度,觸底 onReachBottom 無限加載又需要高度。所以需要在swiper標簽設置動態高度 :style="{height: swiperHeight + 'px'}" 。 onLoad 周期獲取單個list-item的高度。假如所渲染數據有n組數據,則swiper高度為: swiperHeight = baseHeight * n + 加載提示占位高度 。
// swiper動態設置高度,list為需要渲染的數據autoHeight(list) { let num = list.length; // this.loadHeight加載提示語的高度 let listHeight = this.baseItemHeight * num + this.loadHeight this.swiperHeight = Math.max(this.windowHeight, listHeight);},// 獲取靜態高度calcStaticHeight() { return new Promise((resolve) => { let self = this; let tabListHeight; // 獲取tab高度 // 獲取除去tabList高度,全屏高度(空態狀態時需要) wx.createSelectorQuery().select('#tab-list').fields({ size: true }, function (res) { tabListHeight = res.height wx.getSystemInfo({ success: function(resp) { self.windowHeight = resp.windowHeight - tabListHeight } }) }).exec() // 獲取單個item高度 wx.createSelectorQuery().select('#base-item').fields({ size: true }, function (res) { self.baseItemHeight = res.height resolve() }).exec() })}如果頻繁切換swiper會導致卡死,是因為觸摸滑動swiper和點擊選項卡時賦值swiperIndex都會觸發swiper bindchange 事件,這里做了判斷處理。
// 滑動切換swiperTab (e) { // 如果是觸摸滑動切換 if (e.mp.detail.source === 'touch') { if (this.currentTab === e.mp.detail.current) { return false; } else { this.currentTab = e.mp.detail.current this.isLoading = false this.allLoaded = false this.pageNum = 1 this.loadTips = '上拉加載更多' this.getDataList(this.loadTips); } }},// 點擊切換clickTab (tab) { if (this.currentTab === tab) { return false; } else { this.currentTab = tab this.allLoaded = false this.pageNum = 1 this.loadTips = '上拉加載更多' this.getDataList(this.loadTips); }},scroll-view封裝indexList
實現兩種定位方式:點擊定位,按住右側字母indexList滑動定位。

技術難點:按住右側indexList滑動定位,獲取字母indexList的上邊距 offsetTop ,按住滑動時獲取手指距離屏幕頂部的距離 clientY, 手指移動距離為 moveY=clientY-offsetTop, 具體實現如下:
// 索引定位(滑動開始) @touchstart="handlerStart"handlerStart (e) { this.targetIndex = e.mp.target.id},// 索引定位(滑動過程) @touchmove="handlerMove"handlerMove(e) { let keyList = this.keyList; // 手指滑動垂直距離 let moveY = e.mp.touches[0].clientY; let rY = moveY - this.offsetTop; if (rY >= 0) { // apHeight為字母表indexList中單個字母塊高度,計算結果向上取整 let index = Math.ceil((rY - this.apHeight) / this.apHeight); if (index >= 0 && index < keyList.length) { this.targetIndex = keyList[index]; } } else { this.targetIndex = keyList[0] }},坑
view或者text設置border-radius=50%有時候在真機會變形(排除flex布局的影響)。
wxml不支持復雜邏輯,如模版字符串,字符串截取等等。
text設置行高的時候會出現樣式異常,替換成view便可解決此問題。
wx.showLoading和wx.showToast的屬性title不可為空,線上會報錯,影響js執行。
總結
本文只是簡單講一下項目中涉及到的幾處技術要點,歡迎交流。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答