Meituan small program framework mpvue(花名 : no friends) squat guide

My first contact with the small program was probably at the beginning of 17, when the small program was just inside, at that time, I was plagued by various restrictions, one-way binding, no promise, request number limit, package size limit, various anti-human… I feel a lot of malice anyway. Recently, I received a small program project of engineering class. When choosing the technology, I picked up the old things and got familiar with them again. I feel that the small program is still working hard, supporting most es6 syntax, and also producing a Vue MVVM framework Wepy, which also supports Redux state management. Roughly built a demo, ran up, hurriedly although not vue so sour cool, but still quite OK, at least than the native small program syntax close people a lot.

Then began to use Wepy to build the project, write static pages (because the company’s development mode is to write static pages first, waiting for the back end of the classmate interface to bind data), although wepy is easier to use than the native, but there are still a lot of pit, here will not list…..

Just when we were about to finish the static page, we saw a message in the forum one night, and meituan created a small program framework mpVue (I don’t know why, every time I saw the name, I only thought of three words, no friends, haha). I took a look at the official introduction and mainly had the following highlights:

  1. Same development experience as VUE, including Vuex
  2. H5 code conversion ability to compile into small program object code

That is, not only can you develop using the familiar VUE syntax, but it is also possible to compile your H5 pages directly into applets. The project has received nearly 7000 STARS in less than 20 days, which shows that the world has been suffering for a long time.

Built a demo, ran it, and felt like the conscience of the development world. By the way, I copied the static page code of WEpy that I wrote before and found that as long as I changed a little, I could switch from WEpy to MPvue smoothly (the switching time of the whole project was about half a day). I did what I said and cut to MPvue that day. Until now, the project is nearing the end, and the whole development process is really enjoyable.

Bug…. I don’t think I’m here to advertise mpvue today, I’m here to pick a fight…

Here are some of the details I’ve encountered recently in mpVue development that need to be noticed (or different from VUE).

First, I think this is the biggest pit. In addition to missing files, errors will be reported, and other code syntax errors will be reported. The console is silent most of the time (occasionally XXX is undefined). This. XXX =5 will give an error in some cases, and in some cases there is no response.

One time I put

this.dataObject.map(() => { ... Omitted here... })Copy the code

As a result, the. In front of the map is accidentally exposed, and the actual code becomes

this.dataObjectmap(() => { ... Omitted here... })Copy the code

I couldn’t find the cause of the problem for a long time

Second, and this is the uncomfortable part, is that there is no way to call methods (or functions other than computed) in the template syntax in the template’s data binding. One might say, well, I can use computed properties, but what if I want to pass parameters to a function? Look at the following code:

<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>Copy the code

The reason why {{formatCost(item)}} renders the contents as empty strings is because functions are not supported, and you can’t use computed properties in this case, unless you want to write one for each array element

In this case, my solution is to change the data as soon as it is available. In the example above, we can write this in the getData method

Let arr = [3.255,4.1,5,15] // go through the list of elements, then format, add to the costList arr. Map (item => {this.costlist.push = this.formatCost(item) })Copy the code

Third, the Created lifecycle functions in all pages are executed once when the applet is loaded, rather than once every time it enters a page, e.g., I have three pages

pageA

. Leave out some code... Creatted (){console.log('pageA created function executes ')}Copy the code

pageB

. Leave out some code... Creatted (){console.log('pageB created function executes ')}Copy the code

pageC

. Leave out some code... Creatted (){console.log('pageC created function executes ')}Copy the code

And then, instead of going to these three pages, let’s say I now have an Index page, and if I go to this page, I’ll get some output

PageA's created function executes pageB's created function executes pageC's created functionCopy the code

Mounted or onLoad or onReady. Created and Mounted are mpvue lifetimes. OnLoad and onReady are mpvue lifetimes. Mpvue official notes are:

In addition to Vue’s own life cycle, MPVue is also compatible with applets’ life cycle hooks, which originate from the Page of wechat applets. It is not recommended to use applets’ life cycle hooks except in special cases.

OnLoad/Mounted (created) is executed earlier than onLoad/Mounted (created). Will be relatively less bad time (here hang not rendering index according to interface), and the official didn’t explain why not recommend the use of small application life cycle, we also tried to use the small application lifecycle, haven’t found life problem, so we still prefer the priority use small application lifecycle, user experience is king, after all.

4. Attributes mounted on vue. prototype, which are undefined in template syntax, must be computed before they can be used. When using VUE, I like to store the image server path in the vue prototype:

import config from './config'
Vue.prototype.$serverPath = config.serverPath
Copy the code

And then we’re going to do this in the page

<img :src="$serverPath + 'logo.png'" />
Copy the code

This will avoid importing config files on every page. If we release the official version later, we can just modify the config file here. However, this will be written in mpvue, and the actual rendering will be

<image src="undefinedlogo.png" ></image>
Copy the code

To use it in every page, you can only import it in every page, or return this.$serverPath in computed

5. When using a V-for loop, if I want to assign an index to the current item, UNDER VUE, I usually like to do this for convenience

v-for="item,index in list"
Copy the code

Because an extra pair of parentheses is really annoying. But it doesn’t work under MPvue, so you have to do this honestly or you’ll get an error.

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

Six, separate for each page set page header information, there is to provide this function, but the document is not very detailed, after several attempts, just try out.

We can do this in our entry file main.js (vue for now, but I think it should be called config file), and the official documentation probably says so too

This section comes from app and Page entry files, usually main.js. You need to export default {config: {}}, which will be recognized by our loader as a configuration file that needs to be written in JSON.

import Vue from 'vue'; import App from './app'; const vueApp = new Vue(App); vueApp.$mount(); // Export default {// This field will be filled with data to app.json/page.json config: {pages: ['static/calendar/calendar', '^pages/list/list'], // Will be filled in webpack window: {/ / at the top of the bar uniform configuration backgroundTextStyle: 'light' navigationBarBackgroundColor: '# 455 a73, navigationBarTitleText: NavigationBarTextStyle: '# FFF '}}};Copy the code

At the same time, we will automatically fill the Pages field in app.json based on the entry page data. The Pages field is also customizable, with the convention that pages starting with the ^ symbol are placed at the top of the array.

We see that we can configure a global top bar style under config.window, but what if we wanted to specify a style for each page? In fact, the above method is only suitable for configuring the contents of app.json. If you want to add a style for each of your pages, you should do this: Add the following content to the entry file (main.js) that the page belongs to. For example, if I want to set a title for the userCenter/index page, I should add it to userCenter/main.js

Export default {config: {navigationBarTitleText: 'Personal center ',}}Copy the code

NavigationBarTitleText is a config property, whereas config.window is a config property

I wrote a component that is part of a page. For simplicity, I named this component list.vue and referenced it in the parent component:

<template> <! --> <list /> </template> <script> import list from './components/list' export default {components: {list}, // omit other code} </script>Copy the code

The components work, the styling is fine, everything looks fine, but the logic inside the components just doesn’t work. Plus the first point mentioned in this article, will not report errors, let me find a good ah… After investigation, it was found that it was related to the introduction name of the component, which should be the same name as the key word of wechat.

<template> <! --> <listA /> </template> <script> import listA from './components/list' export default {components: {listA}, // omit other code} </script>Copy the code

This will work normally, out of the list, I currently stepped on the Tabbar, so that WHEN I name now, I see some suspected key words, psychological a little shadow. This should be a wechat problem, in short, encountered, write out together.

8, the first time the component load can not execute onShow inside the content, only after hidden and displayed, will be displayed, and the page is entered each time will be displayed, such as we have the code in a component

onLoad () {
  console.log('onLoad')
},
onShow () {
  console.log('onShow')
},
mounted () {
  console.log('mounted')
},
Copy the code

When the page loads, what we expect to print is

onLoad
onShow
mounted
Copy the code

And then actually, just print it out

onLoad
mounted
Copy the code

I have made an Issue of this Issue to the official, but I haven’t received any response yet

NavigateTo (wx. NavigateTo) navigateTo (wx. NavigateTo) navigateTo (wx. NavigateTo) navigateTo (wx. NavigateTo) navigateTo (wx. NavigateTo) navigateTo (wx. NavigateTo) navigateTo (wx. This is also why the page path of the small program is limited to 10 layers at most, because the page you visited is normally kept in memory, which is equivalent to keep-alive in vUE. If you allow too many pages to jump, it is easy to use too much memory.

NavigateBack wx.redirectTo wx.reLaunch can also be used to unload a page using onUnload

9. Canvas will not scroll with the page when placed in scroll View. It seems to be fixed in a certain position, but it can scroll normally in ordinary view. The problem is actually WeChat, official document is the point, but when I met question, didn’t expect to be WeChat official out of problem, a variety of baidu Google, didn’t find it has to do with this problem, even I doubt my own code, then built a project, then direct examination official sample code, it’s the same effect. Later, I was ready to give up and think of other solutions. Unexpectedly, I saw it in the small print at the bottom of the introduction of the scroll View component in the official document today

Tip: Do not use textarea, Map, canvas, and video components in the Scroll view

A closer look at the Canvas component’s documentation shows similar hints

Tip: Do not use canvas component in scroll view, swiper, picker-view, movable-view.

The reason why this point is also included, one is for this problem pit me for several days, I have been thinking of other solutions, two is these days various Baidu Google, there are several similar questions, but no one answered, I will record here, hope that the children who stepped on this pit can be found.

10. Referencing the same subcomponent in two different places will cause the style to not load in both places. If referencing the same subcomponent in one place is ok, why put this problem at the end? Because this is only the previous several versions of scaffolding has this problem, the latter should not have this problem. I have also raised this Issue to the official, and the official replied that the project should be rebuilt with the new version of scaffolding. However, the project was almost finished, so I felt too tired to regenerate and copy the code at this time, so I held an attitude of never giving up. Finally, I found out the reason because of the earlier version of scaffolding. The webpack-mpvue-asset-plugin plugin is missing and will be added automatically in the new CLI. Look at Issue #180

There are also some official points out the problem, here is not a list, interested children can directly view the mpVue official documentation

In addition, I am currently doing a basic tutorial on MPVue. If you are interested in mpvue-tutorials, please go to my Github mpvue-tutorials. Your Star would be my biggest motivation.