mpvue踩坑日記

  1. app.json中pages字段裏的頁面地址不能重複
  2. tabbar中不能設置字體大小(至少在2019.10.10之前是不支持的,希望後續能夠支持吧)
  3. 全局樣式放到app.vue中
  4. 給tabbar設置邊框陰影 官方沒有支持 但是可以變通一下 在app.vue中給page標籤添加僞類
page:after{
  content: '';
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background-color: #FFFFFF;
  box-shadow:0 0 20px 5px rgba(0,0,0,0.06);
  z-index: 9999;
}

5.因爲小程序組件比如view不能再wxss中設置背景圖片,所以在style中寫的背景圖片都是無效的,但是在template中寫行內樣式是可以設置背景圖片的,並且圖片不能使網絡圖片

<template>
    <div>
      <div class="v-personal-head" style="background-image: url('/static/images/img_personal.png');background-repeat: no-repeat;background-size: 100% 100%;"></div>
    </div>
</template>

6.微信image組件如何垂直居中?起因是公司規定禁止使用vertical-align

//... 
<div class="v-item-icon"><img src="/static/icon/[email protected]" alt=""></div> 
//... 
<style scoped> 
.v-item-icon { 
display: flex; 
align-items: center; 
} 
</style>

7.小程序預覽打包時大小不能超過2M 如果超過就是打包失敗 ,可以使用subPackages 參數進行分包操作(注意如果是tabBar中的頁面,不能加入分包中,只能放到主包中 最後將主包中pages重複的頁面刪除)

 

"subPackages": [
  {
    "root": "pages/cBao/",
    "pages": [
      "c/main"
    ]
  },
  {
    "root": "pages/bBao/",
    "pages": [
      "b/main"
    ]
  },
  {
    "root": "pages/aBao/",
    "pages": [
      "a/main"
    ]
  }
],

 

目錄結構就是

-pages

---cBao

------c

--------index.vue

--------main.json

--------main.js

---bBao

------b

--------index.vue

--------main.json

--------main.js

---aBao

------a

--------index.vue

--------main.json

--------main.js

 

8.picker組件mode類型選擇date的話,格式一定是"YYYY-MM-DD"

9.web-view組件有時候不好使,即使把src路徑寫死也是空白頁(這個問題我找了半天時間),結果我使用了網吧裏我網管教我的招數,重啓開發工具,好使了。。。

10.scroll-view的scroll top設置無效,滾動時scrollLower不觸發的坑

<div class="cat-scroll">
<scroll-view :scroll-y="true" :style="{'height': windowHeight}" :scroll-top='scrollTop' :lower-threshold="topHeight"
             @scrolltolower="scrollLower"
             @scrolltoupper="scrollUpper" :scroll-with-animation="true" @scroll="scroll">
             </scroll-view>
</div>
export const windowHeight = () => {
  let systemInfo = wx.getSystemInfoSync()
  return systemInfo.windowHeight + 'px'
}
data() {
  import {windowHeight} from "../../utils";
  return {
    scrollTop: 0,
    windowHeight: windowHeight()//這是獲取當前屏幕的高度的方法
  }
},
methods:{
    //點擊返回頂部
    goToTop(e) {
        this.scrollTop = 1
       this.scrollTop = 0
    }
}

 

<style>
.cat-scroll {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  overflow: hidden;
}
</style>

11.封裝wx.request請求

在utils文件夾下 創建env.js wx-request.js

//env.js
//根據不同的環境更改不同的baseUrl
let baseUrl = '';

//開發環境下
if (process.env.NODE_ENV == 'development') {
  console.log('進入開發環境')
  baseUrl = 'http://192.168.124.14:8089/'

} else if (process.env.NODE_ENV == 'production') {
  console.log('進入生產環境')
  baseUrl = 'http://admin.duoyuka.net/'
}

export {
  baseUrl,//導出baseUrl
}

 

/**
 * wx.request封裝
 * @author dingxinyang
 * @since 2019-09-26
 */


import {baseUrl} from "./env";

const request = (url, method, data, header = {}) => {
  wx.showLoading({
    title: '加載中' // 數據請求前loading
  })
  return new Promise((resolve, reject) => {
    wx.request({
      url: baseUrl + url, // 僅爲示例,並非真實的接口地址
      method: method,
      data: data,
      headers: {
        'content-type': 'application/json' // 默認值
      },
      success: function (res) {
        wx.hideLoading()
        resolve(res.data)
      },
      fail: function (res) {
        wx.hideLoading()
        // reject(false)
      },
      complete: function () {
        wx.hideLoading()
      }
    })
  })
}

const get = (obj) => {
  return request(obj.url, 'GET', obj.data)
}

const post = (obj) => {
  return request(obj.url, 'POST', obj.data)
}

//拋出request post
export default {
  request,
  get,
  post
}

服務器域名配置

每個微信小程序需要事先設置通訊域名,小程序只可以跟指定的域名與進行網絡通信。包括普通 HTTPS 請求(wx.request)、上傳文件(wx.uploadFile)、下載文件(wx.downloadFile) 和 WebSocket 通信(wx.connectSocket)。

從基礎庫 2.4.0 開始,網絡接口允許與局域網 IP 通信,但要注意 不允許與本機 IP 通信。

從 2.7.0 開始,提供了 UDP 通信(wx.createUDPSocket)。

配置流程

服務器域名請在 「小程序後臺-開發-開發設置-服務器域名」 中進行配置,配置時需要注意:

  • 域名只支持 https (wx.requestwx.uploadFilewx.downloadFile) 和 wss (wx.connectSocket) 協議;
  • 域名不能使用 IP 地址(小程序的局域網 IP 除外)或 localhost;
  • 可以配置端口,如 https://myserver.com:8080,但是配置後只能向 https://myserver.com:8080 發起請求。如果向 https://myserver.com、https://myserver.com:9091 等 URL 請求則會失敗。
  • 如果不配置端口。如 https://myserver.com,那麼請求的 URL 中也不能包含端口,甚至是默認的 443 端口也不可以。如果向 https://myserver.com:443 請求則會失敗。
  • 域名必須經過 ICP 備案;
  • 出於安全考慮,api.weixin.qq.com 不能被配置爲服務器域名,相關API也不能在小程序內調用。 開發者應將 AppSecret 保存到後臺服務器中,通過服務器使用 getAccessToken 接口獲取 access_token,並調用相關 API;
  • 對於每個接口,分別可以配置最多 20 個域名。

12.網絡請求

超時時間

  • 默認超時時間和最大超時時間都是 60s;
  • 超時時間可以在 app.json 或 game.json 中通過 networktimeout 配置。

使用限制

  • 網絡請求的 referer header 不可設置。其格式固定爲 https://servicewechat.com/{appid}/{version}/page-frame.html,其中 {appid} 爲小程序的 appid,{version} 爲小程序的版本號,版本號爲 0 表示爲開發版、體驗版以及審覈版本,版本號爲 devtools 表示爲開發者工具,其餘爲正式版本;
  • wx.requestwx.uploadFilewx.downloadFile 的最大併發限制是 10 個;
  • wx.connectSockt 的最大併發限制是 5 個。
  • 小程序進入後臺運行後,如果 5s 內網絡請求沒有結束,會回調錯誤信息 fail interrupted;在回到前臺之前,網絡請求接口調用都會無法調用。

返回值編碼

  • 建議服務器返回值使用 UTF-8 編碼。對於非 UTF-8 編碼,小程序會嘗試進行轉換,但是會有轉換失敗的可能。
  • 小程序會自動對 BOM 頭進行過濾(只過濾一個BOM頭)。

回調函數

  • 只要成功接收到服務器返回,無論 statusCode 是多少,都會進入 success 回調。請開發者根據業務邏輯對返回值進行判斷

 

13.webview配置

如何想要使用webview就需要小程序管理後臺中配置業務域名

開發文檔:在webview 指向網頁的鏈接。可打開關聯的公衆號的文章,其它網頁需登錄小程序管理後臺配置業務域名。

 

14.表單

表單組件又多又複雜,框架可能Hold不住。所以在實際開發中,推薦直接使用小程序的表單組件標籤來寫,而不是使用Web的表單組件標籤來寫。當然了,在mpvue中使用了小程序的組件標籤,數據綁定功能還是完全可以用的。給個示例:

<template>
  <div>
    <picker @change="handlePickerChange" :value="selectedIndex" :range="messages">
      <view class="picker">當前消息:{{ messages[selectedIndex] }}</view>
    </picker>
  </div>
</template>

<script>
export default {
  data () {
    return {
      selectedIndex: 0,
      messages: ['Hello', 'World', 'Haha']
    }
  },
  methods: {
    handlePickerChange (e) {
      console.log(e)
    }
  }
}
</script>

 

 

15.在模板中,動態插入HTML的v-html指令不可用

這條很好理解,小程序的界面並不是基於瀏覽器的BOM/DOM的,所以不能動態的在界面模板裏直接插入HTML片段來顯示。

題外話,如果有在小程序裏插入html片段的需求怎麼辦?可以用<rich-text>組件或者wxParse(https://github.com/icindy/wxParse)來實現。

16.在模板中,用於數據綁定的雙括號語法{{}}中的表達式功能存在諸多限制

在Vue本身的模板內雙括號語法中,我們可以對綁定變量進行比較豐富的處理,比如:

  • 可以調用methods下的函數, 例如:
<template>
  <div>{{ formatMessage(msg) }}</div>
</template>

<script>
export default {
  data() {
    return {
      msg: "Hello,World"
    }
  },
  methods: {
    formatMessage(str) {
      return str.trim().split(',').join('#')
    }
  }
}
</script>
  • 如果變量是對象的話,也可以調用對象的成員方法
<div>{{ msg.trim().split(',').join('#') }}</div>
  • 可以使用過濾器來處理變量,最有用的場景算是格式化數據了
<div>{{ msg | format }}</div>

以上這些好用的功能,在mpvue中,記得都是通通不能用的哦!!!

我們只能在雙括號中使用一些簡單的運算符運算(+ - * % ?: ! == === > < [] .)。

但是也得找些可用的替代方案吶,大夥先考慮使用計算屬性(computed)來做吧。

17.在模板中,除事件監聽外,其餘地方都不能調用methods下的函數

在Vue中,模板裏調用methods部分定義的函數是非常常見的,比如下面這段代碼所示,在v-if指令中調用函數getErrorNum():

<div v-if="getErrorNum() > 0  && code == 10001" class="error">{{ errorMsg }}</div>

可是,在mpvue裏就是不可以用!因爲在小程序原生模板wxml裏就不支持這種函數調用,導致mpvue沒有很好的方式轉譯過去(雖然小程序有wxs,但是感覺翻譯過去mpvue要做的工作會比較複雜)。

所以,可用的替代方案可能還是計算屬性了。

18.在模板中,不支持直接綁定一個對象到style或class屬性上

在Vue中我們可以爲HTML元素的class或style綁定一個對象,並按照對象內的屬性值來決定是否添加對應的屬性名到HTML元素的樣式名。示例如下:

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

<script>
export default {
  data() {
    return {
      classObject: {
        active: true,
        'text-danger': false
      }
    }
  }
}
</script>

上面這段代碼的運行後生成的HTML將是:

<div class="active"></div>

但是在mpvue下面這個特性也不能用,按官方說法是由於涉及到一些性能相關的原因。那如果要動態改變組件的class該怎麼寫呢?官方給出的方式是這樣的:

<div :class="{ active: classObject.active, 'text-danger': classObject['text-danger']}"></div>

其實改動不大,稍微多打了一些字而已,相當於在模板的class裏再定義一個對象罷了。但是據文檔中說這樣會提升性能。好吧,爲了性能,這點麻煩還是能忍受的。但是它又說了:從性能考慮,建議不要過度依賴此......看來即使這樣,也還是有性能問題。

看來最好一點的方案,還是得使用計算屬性,直接生成一串樣式的字符串,綁定到class或style上:

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

<script>
export default {
  data() {
    return {
      classObject: {
        active: true,
        'text-danger': false
      }
    }
  },
  computed: {
    classStr() {
      let arr = []
      for (let p in this.classObject) {
        if (this.classObject[p]) {
          arr.push(p)
        }
      }
      return arr.join(' ') 
    }
  }
}
</script>

19.在模板中,嵌套使用v-for時,必須指定索引index

通常,我們在Vue模板中嵌套循環渲染數組的時候,一般是這個樣子的:

<template>
  <ul v-for="category in categories">
    <li v-for="product in category.products">{{product.name}}</li>
  </ul>
</template>

但在mpvue中使用這種嵌套結構的v-for時,則必須每層的v-for上都給出索引,且索引需取不同名字:

<template>
  <ul v-for="(category, index) in categories">
    <li v-for="(product, productIndex) in category.products">{{product.name}}</li>
  </ul>
</template>

20. 事件處理中的注意點

在mpvue中,一般可以使用Web的DOM事件名來綁定事件,mpvue會將Web事件名映射成對應的小程序事件名,對應列表如下:

// 左側爲WEB事件 : 右側爲對應的小程序事件
{
    click: 'tap',
    touchstart: 'touchstart',
    touchmove: 'touchmove',
    touchcancel: 'touchcancel',
    touchend: 'touchend',
    tap: 'tap',
    longtap: 'longtap',
    input: 'input',
    change: 'change',
    submit: 'submit',
    blur: 'blur',
    focus: 'focus',
    reset: 'reset',
    confirm: 'confirm',
    columnchange: 'columnchange',
    linechange: 'linechange',
    error: 'error',
    scrolltoupper: 'scrolltoupper',
    scrolltolower: 'scrolltolower',
    scroll: 'scroll'
}

除了上面的之外,Web表單組件<input>和<textarea>的change事件會被轉爲blur事件。

然後,像keydown、keypress之類的鍵盤事件也沒有了,因爲小程序沒有鍵盤,所以不需要這些事件。

還有,Vue裏面綁定事件的時候,可以指定事件修飾符,但是在mpvue裏,官方給出了一些注意信息:

  • .stop 的使用會阻止冒泡,但是同時綁定了一個非冒泡事件,會導致該元素上的 catchEventName 失效!【這個親測了一下,感覺是最新版本里修復了還是怎麼的,沒有文檔裏說的這個問題了】
  • .prevent 可以直接幹掉,因爲小程序裏沒有什麼默認事件,比如submit並不會跳轉頁面【也就是不需要支持】
  • .capture 支持 1.0.9 【也就是在 mpvue 1.0.9及以後版本支持】
  • .self 沒有可以判斷的標識 【也就是不支持】
  • .once 也不能做,因爲小程序沒有 removeEventListener, 雖然可以直接在 handleProxy 中處理,但非常的不優雅,違背了原意,暫不考慮【也就是不支持】

所以呢,總之當你在遇到事件相關的問題,請回來查看一下文檔,看看自己是否已經掉在坑裏了。

其他注意事項

另外,在Vue開發Web應用的時候,通常使用vue-router來進行頁面路由。但是在mpvue小程序開發中,不能用這種方式,請使用<a>標籤和小程序原生API wx.navigateTo等來做路由功能。

還有就是請求後端數據,我們通常在Web開發中使用axios等ajax庫來實現,但是在小程序開發中也是不能用的,也請使用小程序的原生API wx.request等來進行。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章