mpvue踩坑日记

Posted 熬夜的小青年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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/icon_hot@2x.png" 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等来进行。

 

 

以上是关于mpvue踩坑日记的主要内容,如果未能解决你的问题,请参考以下文章

cocos creator踩坑日记(持续更新中...)

mpvue 踩坑之src数据绑定出错

Android 踩坑日记 - RecyclerView 布局问题

初识MpVUE开发微信小程序踩坑记录

人工智能(AI)库TensorFlow 踩坑日记之二

vue 组件传值踩坑日记 1