Megalo is a Vue based applet framework (yes, Vue based applet framework again), but it supports not only wechat applet, but also Alipay applet, and it also supports more Vue features when developing.

background

For users, small programs provide a better experience, but for developers, it takes multiple sets of code to make an application run on multiple platforms. How to improve the efficiency of small program development is a headache for many developers.

There are also related solutions in the industry, such as Taro and MPvue, both of which are based on the React and VUE development models, allowing developers to develop small programs with the react or VUE models they are familiar with, improving the development efficiency.

The release of MPvue has given us a lot of inspiration, and earlier we developed a mini program framework called Mpregular based on RegularJS, netease’s own front-end framework. During the development and actual use of Mpregular, we found that if the small program framework supported only a subset of the original framework’s features (e.g. no filter support, template complex expressions, etc.), development efficiency was significantly reduced.

So, we did a lot of work on the solution to support more features and reduce the differences between small programs and before H5 development. Mpregular has been widely used in koala’s small program business. Students who developed the related business said that the cost of learning has been reduced and the development efficiency of cross-end business (H5 and small program) has nearly doubled.

After a period of verification, we decided to implement the solution with VUE again, one to adapt to the change and upgrade of the technology stack, and the other to do a little bit of work for the community, which led to Megalo.

features

Support for more template syntax features

Megalo is closer to Vue’s native development model because it supports more features than other small program development models.

features Small program mpvue megalo
Computed attribute ⭕ ️ ⭕ ️
V-model bidirectional binding ⭕ ️
Slot slot ⭕ ️ ⭕ ️ ⭕ ️
Scoped – slot slot ⭕ ️
The filter filter ⭕ ️
V – HTML rich text ⭕ ️
Interpolation of complex expressions ⭕ ️

As you can see from the table, one of the biggest features of Megalo is that it supports more Vue syntax features. This means that if you have a requirement to migrate existing Vue code to applets, not much needs to be changed. Because your code is likely to use a lot of filters, scoped-slots, and complex expression interpolation.

The basic grammar

Support vUE basic template syntax, including V-for, V-IF. There are no restrictions on how class and style can be bound, and official usage is supported.

<! -- v-if & v-for -->
<div v-for="(item, i) in list">
  <div v-if="isEven(i)">{{ i }} - {{ item }}</div>
</div>

<! -- style & class -->
<div :class="classObject"></div>
<div :class="{ active: true }"></div>
<div :class="[activeClass, errorClass]"></div>
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<div :style="styleObject"></div>
<div :style="[baseStyles, overridingStyles]"></div>
Copy the code

slot & scoped-slot

Supports slot and scoped-slot.

<div>
  <Container>
    <Card>
      <div slot="head"> {{ title }} </div>
      <div> I'm body </div>
      <div slot="foot"> I'm footer </div>
    </Card>
  </Container>
  <List :list="list">
    <span slot-scope="scopeProps">{{ scopeProps.item.label }}</span>
  </List>
<div>
Copy the code

Complex expressions & filter

You can write complex expressions inside the template, call methods on the instance, of course, you can also use the more concise Filter syntax, as usual with Vue development.

<div>
  <div>{{ message.toUpperCase() }}</div>
  <div>{{ toUpperCase( message ) }</div>
  <div>{{ message | toUpperCase }}</div>
</div>
Copy the code

v-html

To use V-HTML you need to add the @megalo/vhtml-plugin and introduce the template parser Octoparse.

import Vue from 'vue'
import VHtmlPlugin from '@megalo/vhtml-plugin'

Vue.use(VHtmlPlugin)
Copy the code

Using the V-HTML directive, you can then render the HTML in the applet.

<div v-html="'<h1>megalo</h1>'"></div>
Copy the code

Better data update performance

The official description of the applet explicitly states that if the setData call is used to update data in large quantities or more frequently, it will cause performance problems. Megalo has optimized this for developers in the framework. Each time the data changes, Megalo updates only the changed data in the view, minimizing the amount of data updates in setData and limiting the frequency of updates.

As shown in the following code, if the view only needs to display the user.name field, only the user.name string will be updated to the view layer during data synchronization. The rest of the fields will not be synchronized to the applet object.

<div>{{ user.name }}</div>
<script>
export default {
  data() {
    return {
      user: {
        name: 'kaola'.age: 3.favorite: [
          'encalyptus'.'sleeping']}}}}</script>
Copy the code

Support for more platforms

Since the beginning of this year, all major traffic platforms have made some moves in the field of small programs. Ant Financial service established small program business division, And Baidu and Toutiao have also launched their own small programs. Megalo already supports wechat and Alipay Miniprograms, and baidu Miniprograms and others are in the works.

Wechat and Alipay small programs

use

Developing with Megalo is as simple as configuring @Megalo /target on a common Vue project Webpack build configuration and introducing @Magalo /template-compiler. If you need to compile alipay applet, you only need to set platform: ‘Alipay’.

const { createMegaloTarget } = require('@megalo/target');
module.exports = {
  target: createMegaloTarget( {
    compiler: require('@megalo/template-compiler'),
    platform: 'wechat'})// Other WebPack configurations such as Vue-loader, etc
};
Copy the code

Then, you can develop the applet just as you would a Vue application. See Megalo-demo for an example.

If you want to develop in typescript, see Megalo-TS-Simple.

implementation

Small programs are mainly composed of Service(JavascriptCore) and View(WebView) in structure (wechat and Alipay small programs have similar structure, the following are wechat small programs as an example, and referred to as small programs for short), respectively running on independent environment, there is no data sharing channel between them. The communication mode of the two is to encapsulate the data in JS script and pass it. The Page instance is in the Service, passing the data to the View via the setData method. The View passes events triggered by the View layer to the Service through event binding. DOM nodes in the view layer cannot be manipulated in the Service layer.

In practice, the applet logic and template need to be written in.js and.wxml files, executed in Service and View respectively. To run Vue on the browser side in a small program, you need to convert the.vue template fragment to a.wxml file and modify the Vue runtime section to remove the DOM operations. Communicates with the View through the API on the page instance in the applet’s Service.

The final operation effect is that when the data on Vue’s VM is updated, VDOM will be re-rendered. In the patch phase of, the framework does not operate THE DOM, but updates the changed data to the view layer through the setData method on the Page to complete the view update of Vue and small programs. That’s what’s going on at the bottom of Megalo.

The implementation of Megalo is mainly divided into the following four parts, each of which will be introduced in the following article.

The life cycle

Each Page is an instance of a small program. There are many lifecycle hooks for pages, but the two key lifecycle hooks for instance creation are onLoad and onReady, which are triggered when the Page loads after the instance is initialized and when the first Page rendering is complete, respectively. To establish a connection between the Vue instance and the applet instance, you need to initialize the corresponding Vue root instance in the onLoad hook function after the applet Page instance is created, and mount the Page instance to the $mp of the Vue instance. This also triggers the Vue lifecycle hook created. After the page is first rendered, the $mount method is called, and instead of mounting the DOM node in the browser, the data on the Vue instance is initialized into the view layer. Thus, the Vue instance is linked to the Page reality of the applet.

In addition to these two lifecycle hooks, lifecycle hooks such as onShow and onHide in small programs also attempt to trigger the same name hook function on the Vue instance when firing, to implement lifecycle binding between the two instances. When the applet page exits from destruction, the onUnload hook is triggered and the instance of the Vue is destroyed.

Template transformation

Applets have their own template syntax and filename suffixes, so during the build phase, we extract the template portion of the.vue file and convert it to the corresponding.wxml file. The label name and syntax are translated accordingly, as shown in the figure.

This part is done during the construction phase, which means that Megalo does not support the render function. In addition to converting the template to.wxml during the construction phase, each node in the template needs to be transformed and the relevant node tag information is added to the render function of the production, which is required for the data map and event broker.

Data mapping

Since we cannot directly manipulate the DOM of the view layer, we can only use the page. SetData method to complete the mapping of data to the view layer. The simplest way to do this is to collect all the data on the Vue instance and update the page instance by calling the page. SetData method, which mounts the data on the page instance and passes the data to the view layer.

However, there are two disadvantages to this crude approach to updating:

I. A full update of data on the VM makes it impossible to distinguish which data is needed by the view layer. Redundant data will be updated to the page instance. In the example below, the view layer only needs to present two strings, and if there are two large arrays on the VM, they will also be mindlessly synchronized to the page.

Ii. The data synchronized to the page instance is actually the original data, not the actual data to be displayed by the view layer, so the formatting and transformation of the display data need to rely on the parsing ability of the small program template, which causes that some template syntax supported by Vue cannot support. Examples include filters, complex expressions, passing class objects, and so on.

Of course, the above two disadvantages will not affect the functional development, but in the actual business development, it will make the development experience inconsistent, especially when H5 code is migrated to small programs, to the efficiency of the impact. In order to solve this problem, Megalo adopts another way to update the data on vnode generated when render to the view. The data of Vnode is the display data that has been processed. According to vnode, the data structure of each node is constructed and then synchronized to the view layer.

For example, in the following code, Megalo marks each node during the construction phase so that the vNode generated at Render corresponds to each interpolation in the template.

<! -- Vue template before compilation. Vue -->
<div :class="ClassObj">
  {{ date | format( 'YYYY' ) }}
</div>

<! -- compiled small program template.wxml -->
<view class="{{ node_1.class }}">
  {{ node_2.text }}
</view>
Copy the code

In this way, only the two strings of data required by the view layer are synchronized to the Page instance of the applet. The rest of the data is considered irrelevant to the view and will not be synchronized.

export default {
  data() {
    return {
      classObj: {
        'kaola': true
      },
      date: new Date(),
      users: {
        // big object}}}}Copy the code

As shown in the figure below, the vnode rendered by Vue will be mapped to the page with a specific data structure and then synchronized to the applet view layer.

Data mapping in this way better supports Vue’s template syntax and reduces the amount of data transferred when updating views, circumventing setData’s performance issues at the framework level.

The event agent

After the applet view triggers an event, it will notify the Event object to the Page instance, so we only need to proxy all the events in the view layer to the Page. Proxy method, and then rely on this method to find the corresponding VM and handler from the instance tree of Vue to handle the event. To achieve this, in addition to converting the event listener method to proxy when compiling the template during the construction phase, the corresponding component COMPID and node NODEID need to be marked on the element via data-.

<! -- Vue template before compilation. Vue -->
<div @click="onClick"></div>

<! -- compiled small program template.wxml -->
<view bindtap="proxy" data-compid="0" data-nodeid="0"></view>
Copy the code

When the event is triggered, the proxy method will obtain the corresponding ID information and event type from the Event object, and then start to search from the root VM of Vue, and finally find the corresponding handler on vnode and perform event processing, so as to complete the applet event to the event agent of Vue instance.

Present and Future

Megalo has been gradually used in the development of small program applications in Koala, but Megalo’s data mapping scheme has already been validated by Mpregular in a number of small program applications in Koala. Megalo now supports typescript development and alipay applets.

Baidu intelligent small program support is also in the plan. At the same time, we also plan to develop a UI component library and API library compatible with various platforms, trying to minimize the differences between application development across H5 and various small program platforms, and improve the development efficiency.

github

  • megalo
  • The document
  • Megalo – demo sample
  • Megalo-aot build tool
  • Megalo-examples Examples of projects

reference

  • mpvue
  • mpregular
  • Small program optimization suggestions