美团小程序框架mpvue蹲坑指南

美团小程序框架mpvue(花名:没朋友)蹲坑指南

第一次接触小程序大概是17年初,当时小程序刚刚内侧,当时就被各种限制折腾的死去活来的,单向绑定, 没有promise,请求数限制,包大小限制,各种反人类,...反正我是感受到了满满的恶意. 最近接到一个工程类的小程序项目,做技术选型的时候,又把以前的东西捡起来看了看,重新熟悉了一下, 感觉小程序还是有在努力的,支持大部分es6语法了,还出了一个类Vue的框架wepy,还支持redux状态管理, 就大致建了个demo,跑了起来,感觉虽然没有vue那么酸爽,但是还是挺ok的,至少比原生的小程序语法亲民很多.

然后就开始用wepy搭项目,写静态页面(由于公司的开发模式是先写静态页面, 等待后端的同学接口出来了再绑定数据),虽然wepy用起来比原生的顺手, 但是还是有很多坑的,这里就不列举了.....

就在我们静态页面快写完的时候,某天晚上论坛的时候看到一条消息, 美团出了个小程序框架mpVue (不知道为什么,每次看到这个名字,我只想到3个字,没朋友,哈哈), 大致看了一下官方的介绍,主要有一下亮点:

  1. 跟vue一样的开发体验,包括vuex
  2. H5代码转换编译成小程序目标代码的能力

也就是说,不但可以用我们熟悉的vue语法开发,还有可能直接把你的h5页面编译成小程序. 该项目到目前位置,开源不到20天,已经收到将近7000个star,可见天下苦秦已久。

建了个demo,跑了一下,感觉简直就是开发界的良心之作啊.顺便把之前写的wepy的静态页面代码复制过来看了一下, 发现只要改动一点点,就可以顺利从wepy切换到mpvue上来(整个项目的切换时间在半天左右). 说做就做,当天就切到mpvue.一直到现在项目接近尾声了,整个开发过程,真是令人愉悦.

Bug....我今天好像不是来给mpvue做广告的,我是来找茬的..

下面就盘点一下我最近用mpvue开发,遇到的一些需要需要注意的细节.(或者说跟vue不同的地方)

一, 这个个人感觉是最大的坑,除了缺少文件会报错外,其他的代码语法错误等, 控制台大部分时间都是安静的(偶尔也会报一个xxx is undefined) 比较经常碰到的是这样 this.xxx =5 有些情况下会报错,而有些情况下则没有任何反应, 具体什么情况下会,什么情况下不会,我现在还没摸出规律来..

有一次我把

this.dataObject.map(() => { ...这里省略... })

结果map前面的 . 不小心给露掉了,实际代码变成

this.dataObjectmap(() => { ...这里省略... })

结果找了半天没找到问题的原因

二, 这个也是比较难受的地方,就是模板的数据绑定里面,没办法在模板语法里面调用methods方法 (或者说没办法调用computed以外的函数),有人也许会说,那可以用computed属性,那如果我想给函数传参怎么办? 看下面代码:

<template>
  <view v-for="item in costList" >
    {{formatCost(item)}}
  </view>
</template>

<script>
export default {
  data(){
    return{
      costList:[]
    }
  },
  methods: {
    formatCost(item){
    return item.toFixed(2)
    },
    getData(){
    let arr = [3.255,4.1,5,15]
    this.costList = arr
    }
  }
</script>

这个时候 {{formatCost(item)}}里面的内容,会渲染成空字符串,理由就是因为不支持函数,而且这中情况, 也无法使用computed属性,除非你想为每个数组元素写一个computed

这种情况,我的解决方案是在在获取到数据的时候,就先把数据改了.如上面的例子,我们可以在 getData方法里面这样写

let arr = [3.255,4.1,5,15]
// 遍历数组里面的元素,然后格式化一下,添加到 costList里去
arr.map(item => {
    this.costList.push = this.formatCost(item)
})

三, 所有页面里面的created生命周期函数 都会在小程序加载的时候, 一次性执行,而不是每进入一个页面执行一次,如,我有3个页面

pageA

...省略一些代码...
created(){
    console.log(‘pageA 的 created函数执行‘)
}

pageB

...省略一些代码...
created(){
    console.log(‘pageB 的 created函数执行‘)
}

pageC

...省略一些代码...
created(){
    console.log(‘pageC 的 created函数执行‘)
}

然后,启动小程序,不进入这3个页面,假设我现在有一个index页面,我们打开这个页面,会有一下输出

pageA 的 created函数执行
pageB 的 created函数执行
pageC 的 created函数执行

这个其实很好解决,用mounted或者onLoad或者onReady代替,说到这几个函数,那就顺便提一下, 这里的created和mounted是vue(mpvue)的生命周期,而onLoad、onReady是小程序的生命周期,mpvue官方给的说明是:

除了 Vue 本身的生命周期外,mpvue 还兼容了小程序生命周期,这部分生命周期钩子的来源于微信小程序的 Page, 除特殊情况外,不建议使用小程序的生命周期钩子。

但是官方给的生命周期图示里面,也表明了,小程序的onLoad、onReady比created、mounted执行的早, 也就是说如果我们在和onLoad onReady里面去请求数据的话,会相对的减少白屏时间(这里说的白屏是指数据未渲染的界面), 而且官方没说明为什么不建议使用小程序的生命周期,我们也尝试了,用小程序的生命周期,没发现生命问题, 所以我们还是比较倾向优先使用小程序的生命周期,毕竟用户体验才是王道。

四、挂载在Vue.prototype上的属性,在模板语法里面是undefined,必须经过computed计算过一下才能用。 在用vue的时候,我喜欢把图片的服务器路径存到vue的原型里面:

import config from ‘./config‘
Vue.prototype.$serverPath = config.serverPath

然后 我们在页面里面这样用

<img :src="$serverPath + ‘logo.png‘" />

这样 就可以避免在每个页面导入config文件,后期如果我们发布正式版的时候,只要在这边修改一下config配置文件就可以了 然额,这样写在mpvue里面,实际渲染出来的会是

<image src="undefinedlogo.png" ></image>

要想在每个页面里面使用,只能乖乖在每个页面里面导入,或者在computed里面返回this.$serverPath

五、用 v-for循环的时候,如果要给当前项指定一个索引,在vue下,为了省事,我通常喜欢这样做

v-for="item,index in list"

因为多打一对括号真的是很烦人。但是在mpvue下面却不行,你必须老老实实这样写,否则会报错。

v-for="(item,index) in list"

六、单独为每个页面的设置页面头部信息,有提供这个功能,不过文档不是很详细,几经尝试,才试出来。

我们的入口文件main.js(延续vue的叫法,暂且这么称呼吧,其实我觉得应该叫配置文件)里面可以这样配置, 官方文档大概也是这么说的

这部分内容来源于 app 和 page 的 entry 文件,通常习惯是 main.js,你需要在你的入口文件中 export default { config: {} },这才能被我们的 loader 识别为这是一个配置,需要写成 json 文件。

import Vue from ‘vue‘;
import App from ‘./app‘;

const vueApp = new Vue(App);
vueApp.$mount();

// 这个是我们约定的额外的配置
export default {
    // 这个字段下的数据会被填充到 app.json / page.json
    config: {
        pages: [‘static/calendar/calendar‘, ‘^pages/list/list‘], // Will be filled in webpack
        window: {  // 顶部栏的统一配置
            backgroundTextStyle: ‘light‘,
            navigationBarBackgroundColor: ‘#455A73‘,
            navigationBarTitleText: ‘美团汽车票‘,
            navigationBarTextStyle: ‘#fff‘
        }
    }
};

同时,这个时候,我们会根据 entry 的页面数据,自动填充到 app.json 中的 pages 字段。 pages 字段也是可以自定义的,约定带有 ^ 符号开头的页面,会放到数组的最前面。

我们看到,可以在config.window下面配置全局的顶部栏样式,但是如果我们想为每个页面指定一个样式呢?事实上, 以上方法只适合配置app.json里面的内容,如果你想要为你的每个页面都添加一种样式,那么应该这样做: 在页面所属的入口文件(main.js)里面添加以下内容,比如我想为 userCenter/index页面设置一个标题, 应该在userCenter/main.js里面加入

export default {
  config: {
    navigationBarTitleText: ‘个人中心‘,
  }
}

注意 这里跟上面那个全局配置不同的是,配置内容navigationBarTitleText是config的属性, 而全局配置里,则是config.window的属性

七、组件的命名问题,有一次,我写了一个局部的组件,为什么叫局部的组件呢,因为我只在某个页面里面使用, 所以为了简单化,我给这个组件取了个名字叫list.vue,然后在父组件引用:

<template>
<!-- 省略其他代码 -->
    <list />
</template>
<script>
  import list from ‘./components/list‘
  export default {
    components: {list},
    // 省略其他代码
  }
</script>

组件能正常显示,样式也没问题,一切看上去都是那么的正常,然而组件里面的逻辑就是不会执行。 加上本文第一点提到的,不会报错,让我一顿好找啊... 经过排查发现,跟组件的引入名称有关,应该是跟微信的关键字同名了。

<template>
<!-- 省略其他代码 -->
    <listA />
</template>
<script>
  import listA from ‘./components/list‘
  export default {
    components: {listA},
    // 省略其他代码
  }
</script>

这样就能正常运行,出了list,我目前踩到的还有tabbar,搞得我现在命名的时候,看到一些疑似关键的字眼,心理都有点阴影。。 这个应该是微信的问题吧,总之遇到了,就一块写出来。

八、组件第一次加载的时候不能执行onShow里面的内容,只有在隐藏又显示后,才会显示,而页面却每次进入都会显示 例如我们在一个组件里有一下代码

onLoad () {
  console.log(‘onLoad‘)
},
onShow () {
  console.log(‘onShow‘)
},
mounted () {
  console.log(‘mounted‘)
},

页面加载的时候,我们期望打印出来的是

onLoad
onShow
mounted

然后实际上,只打印出

onLoad
mounted

说到这里,我们顺便看看小程序的页面跳转方式,小程序在一个页面跳转(调用wx.navigateTo)到另一个页面的时候, 并不会销毁原来的页面,而是转到后台去,并且执行原页面里面的onHide里的代码, 这也是为什么小程序的页面路径最多只能十层,因为你访问过的页面,正常都会保存在内存里,相当于vue里的keep-alive, 如果允许跳转非常多页面的话,很容易导致内存使用过高。

当然,我们也可以使用wx.navigateBack wx.redirectTo wx.reLaunch 来销毁页面,这3个方法,会调用页面的onUnload函数

九、canvas放在scroll-view不会随着页面滚动,看起来好像是fixed固定在某个位置的,但是在普通的view里面却可以正常滚动。 这个问题其实是微信的问题,官方文档里面是有说明这点,不过我遇见问题的时候,没想到会是微信官方出的问题,各种百度谷歌, 都没找到这跟这个问题有关的,甚至我很怀疑是我自己代码的问题,于是新建了一个项目,然后直接考官方的示例代码,也是一样的效果。 后面就准备放弃,想其他解决方案了,没想到今天在官方文档 -scroll-view组件的介绍的最底部的 小字 里看到了

tip: 请勿在 scroll-view 中使用 textarea、map、canvas、video 组件

进一步查看了canvas组件的文档,发现也有类似的提示

tip: 请勿在 scroll-view、swiper、picker-view、movable-view 中使用 canvas 组件。

之所以把这一点也算进来,一是为这个问题坑了我好几天,我都在想其他方案了,二是这几天各种百度谷歌, 是有搜到几个类似的问题,但是都没人回答,我就在这边记录一下,希望后面踩到这个坑的童鞋能搜到。

十、同一个子组件,在2个不同的地方引用,会导致2个地方的样式都加载不了,而如果只在一个地方引用却没问题, 为什么把这个问题放到最后? 因为这只是前几个版本的脚手架有这个问题,后面的应该就没有这个问题了。 这个问题我也给官方提过Issue,官方给的回答是用新版本的脚手架重新生成项目,但是项目都快做完了, 这个时候重新生成,然后拷贝代码,感觉心太累了,所以抱着不折腾不罢休的态度,终于找到原因,是因为早期版本的脚手架, 缺少了 webpack-mpvue-asset-plugin 这个插件,新版的cli里面会自动添加这个插件。具体看Issue #180

还有一些官方明确指出的问题,这里就不一一列举了,有兴趣的童鞋可以直接查看mpvue官方文档

原文地址:https://www.cnblogs.com/xzqyun/p/9199797.html

时间: 2024-08-30 02:32:32

美团小程序框架mpvue蹲坑指南的相关文章

美团小程序框架mpvue入门教程

自打写了 美团小程序框架mpvue蹲坑指南, 一发不可收拾,今天趁周末空闲,来写个mpvue(没朋友)的简单入门教程,本教程只针对新手,老鸟勿喷. 另外,我还专门为本文做了一个简单的项目,如果懒得从头开始搭项目的童鞋,可以直接去我的 github上克隆到本地, 安装一下依赖,即可直接在此基础在开发,不需要做任何配置.如果你觉得该项目对有帮助, 请顺便给我Star,你们的支持是我最大的动力,谢谢! 好了,我们进入主题,首先,请允许引用一下美团官方对mpvue的介绍 mpvue是一个使用 Vue.j

美团小程序框架mpvue入门

mpvue 主要特性 使用 mpvue 开发小程序,你将在小程序技术体系的基础上获取到这样一些能力: 1. 彻底的组件化开发能力:提高代码复用性 2. 完整的 Vue.js 开发体验 3. 方便的 Vuex 数据管理方案:方便构建复杂应用 4. 快捷的 webpack 构建机制:自定义构建策略.开发阶段 hotReload 5. 支持使用 npm 外部依赖 6. 使用 Vue.js 命令行工具 vue-cli 快速初始化项目 7. H5 代码转换编译成小程序目标代码的能力 如果你有过vue的开发

零基础入门 实战mpvue2.0多端小程序框架

第1章 课程快速预览(必看!!!)在这一章节中,老师讲带领你快速预览课程整体.其中,涉及到为什么要做这么一门实战课程.制作一个小程序的完整流程是怎么样的,以及如何做项目的技术选型. 第2章 30 分钟快速入门微信小程序(已掌握,可略过)在这一章节中,老师讲带领你从如何注册微信小程序开发者账号.工具的下载开始,到完成第一个小程序,再到组件与 API 的使用整个过程,最后来总结微信原生小程序的缺点. 第3章 30 分钟快速入门 Vue.js 框架(已掌握,可略过)在这一章节中,老师将带领你从第一个

mpvue最佳实践 , 美团出的一个小程序框架

看手机微信,看到说美团出了1个小程序框架,  mpvue 搜下来试试,看了网上的一个对比 ----------------- 以下为引用 我们对微信小程序.mpvue.WePY 这三个开发框架的主要能力和特点做了横向对比,帮助大家了解不同框架的侧重点,结合业务场景和开发习惯,确定技术方案.对于如何更好地使用 mpvue 进行小程序开发,我们总结了一些最佳实践. 使用 vue-cli 命令行工具创建项目,使用Vue 2.x 的语法规范进行开发 避免使用框架不支持的语法特性,部分 Vue.js语法在

【小程序】mpvue框架

前置开发环境 node.js,vue-cli,微信开发者工具 创建项目 vue init mpvue/mpvue-quickstart firstapp 进入目录npm install安装依赖后npm run dev,再打开微信开发者工具导入 文件目录结构 1)build目录 build目录下是一些用于项目编译打包的node.js脚本和webpack配置文件.一般情况下不需要修改这些文件. 2)config目录 config目录下包含了用于开发和生产环境下的不同配置,dev.env.js用于开发

【WePY小程序框架实战四】-使用async&amp;await异步请求数据

[WePY小程序框架实战一]-创建项目 [WePY小程序框架实战二]-页面结构 [WePY小程序框架实战三]-组件传值 async await 是对promise的近一步优化,既解决了promise链式then的这种写法壁垒,又让异步请求更像同步,若对async await不太了解的同学可以直接参考阮一峰老师的文章async 函数的含义和用法,这里我们只关注怎么在小程序wepy架构中如何使用. 依赖库 import 'wepy-async-function' app.wpy中启用 export

[转] 扩展微信小程序框架功能

通过第三方 JavaScript 库,扩展微信小程序框架功能. 扩展微信小程序框架功能(1)——Promise ES6 对 Promise 有了原生的支持,但微信开发者工具更新版本(0.11.112200)后, 移除了开发者工具对 ES6 中Promise 特性原生的支持, 需要引入第三方的 Promise 库. 扩展微信小程序框架功能(2)——Generator Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同. 扩展微信小程序框架功能(3)——函数功能增强

小程序框架之场景层

(1)框架 小程序开发框架的目标是通过尽可能简单.高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务. 整个小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View).小程序提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑. (2)响应的数据绑定 框架的核心是一个响应的数据绑定系统,可以让数据与视图非常简单地保持同步.当做数据修改的时候,只

微信小程序搭建mpvue+vant+flyio

导语 上一篇文章微信小程序搭建mpvue+vant已经介绍了如何搭起mpvue项目及引入vant,本篇文章继续在它的基础上,引入flyio,并做一些封装,目的是为了在小程序发起请求. 这时读者会有些疑问,小程序已经有了request,为什么还用flyio?这不是造轮子吗?我是这么想的,其实现在不管是mpvue,还是wepy都好像还不能完美编译出微信小程序和h5版本.为了以后应对老板有创建h5版本的想法,我们应该为以后复用小程序代码做好准备工作.既然h5也会有ajax,flyio也支持小程序和h5