Small program framework WEPY from entry to abandon the pit collection

A little introduction to WEPY

Because small the grammar of the program design is a little fan, so the x1 is not convenient to modular and made a number of the framework of x2 GeChang so convenient to the development of small programs, tencent to see other people’s house were out of the framework that seems small programs I could really is not very convenient development, that I also give a 🤔 so x3 WePY so was born.

That gosling goose 🐧 you early why go ah, why not small program design good use a little bit! Programmers have fun!

Just like a native app, can’t you follow Electron’s lead and hand over the interface to the native HTML of the web page and make a bunch of weird problems with all kinds of useless components.

Programmers why difficult program ape 😂

Sorry to be excited 🙄

In fact, WePY is one of the earliest small program frameworks

Weby is a Vue.js development style that supports features such as Props, mixins, Computed, Slot, componencialization/modularity, NPM dependency, and so on. Promise/Async, ESnext, Less/Sass/Styus, Babel/ TypeScript is a small program development framework.

The syntax is a little bit more Vue.js. As a React party I don’t really like it, but maybe the Vue party doesn’t necessarily like it either. After all, it’s just like, not quite the same, developed with the seemingly inconsistent behavior of Vue.js.

So much for the gossip, let’s get down to business.

Those are the things to watch out for

This section refers to <u>Little colorIn the < u > < / u >2018-03-20</u> post on SegmentFaultWepy- small procedures to step on pit

ALL CREDIT GOES TO HIM THANKS ALOT

The first is the document class:

WePY homepage

Official documentation of WEPY

Small program official documentation

WePY Github Issues

Then there are some key points:

1. Data and Data binding

1.1 All data that may be used should be given value in advance, that is, it should be initialized in data first; Otherwise, the dirty data check process will not be triggered when the data is updated later, and therefore the page rerender will not be triggered.

When updating data, use this.foo = bar instead of WeChat’s native this.setData method.

Class Fn extends Weby.page {data = {foo: 1, // bar: 2, bar} someFunction() {this.foo = 10; // This. Bar = 20; }}

1.3 Data can be bound in the template with the form :foo=bar. Note that non-character types (such as Boolean values) and variables are treated as strings with double curly braces. For other unbound, the content to be displayed directly can be wrapped in double curly braces. Simple operations can be performed within double curly braces, but JavaScript template strings or other method operations are not supported.

// Template <component :name="{{myName}}" bb0 // OK: render {{Greeting}} // OK: render {{new + 'World! {' ${Greeting} World! '}} // Unsupported template string {{' ${Greeting} World! '}} // Error: JS method calls are not supported {{String(Greeting).trim()}} </component>
// Script
class Foo extends wepy.page {
  data = {
    myName: 'WePY',
    greetings: 'Hello',
  }
}

1.4 The operation method is bound with @tap=function. Almost all WeChat native methods bindFn= Fn can be written as @Fn= Fn.

// Template // bindTap =fn < view@tap ="fn"></view> // Script class Foo extends Weby.page {methods = {fn: () => {},}}

2. Methods & Computed

2.1 The methods in class contain only the event methods used by the template. Other custom methods should be on the same level as the methods themselves.

// Template
<view @tap="fn"></view>

// Script
class Foo extends wepy.page {
  methods = {
    fn: () => {
      this.doSomeThing();
    },
  }

  doSomeThing: () => {}
}

2.2 Template events provide “method suffixes” as syntax sugar in place of native writing. Default,. Stop, and. User suffixes are available, and the most common is. Stop, which is equivalent to native catch.

// Template //.default does not say < view@tap ="fn"></view> //. Stop is a catch. < view@tap ="fn"></view>

2.3 Computed and Watcher are basically similar to Vue.js, but I do not introduce ~

3. Mixin & Components

3.1 Mixin back-end programming friends should be familiar with a little, can provide common methods for different places to use. In this case, it can read the shared data directly (read from a Redux, etc.), but be aware that when a Mixin uses data from a Redux, the connect of the data itself is defined in the page to which it refers. It seems that mixins themselves can’t connect data in Redux.

3.2 You can’t use this.foo = bar in mixins to set the value on the page because the context is inconsistent and will not take effect.

3.3 The order of execution in mixins is the reverse of that in vue.js. In vue.js, the functions in the Mixin are executed first, and then the functions of the component itself. Here the order of execution is reversed.

Note: In vue.js, hook functions are executed in mixins before the component’s own; Vue.js methods that have the same name as mixins will only execute their own methods.

3.4 Do not use suffix names when importing components:

// Good ; -) import Xxx from '.. /xx'; // Damned :-( import Xxx from '.. /xx.wpy';

Now comes the most frustrating part of 3.5 — the components in Weby. It’s components are all “singleton”, which means that when you are in the same page to make the same component multiple times, show that “more than” a component of its binding content will be updated as the last one, you can’t give them bound to the different content, you use a component can only enjoy the advantage on the style, completely don’t know what what 🤷 came ️

/ / Template < view wx: for = "{{list}}" > < comp: number. The sync = "{{item}}" > < / comp > / / you can't do this, because it does not accept variable < / view >
// Script import Comp from '.. /Comp'; class Foo extends wepy.page { data = { list: [1, 2, 3, 4], } components = { comp: Comp, } }

Bad = = | |

3.6 For both native and non-native components, the template logic will always “look less fixed”, such as:

// Correct-omit to true <scroll-view scroll-y></scroll-view> // Error - Boolean value cannot be bracketed< scroll-view scroll-y="{{true}}"></scroll-view> <scroll-view scroll-y="true"></scroll-view> // Correct - but the first argument this method takes is an instance of the current Class. < view@tap ="toggleSomeThing"></view> // error - Boolean value with parenthetical < view@tap ="toggleSomeThing(true)"></view> // correct <view @tap="toggleSomeThing({{true}})"></view>

3.7 There is an occasional case where other attributes such as class are occasionally “ignored” when wx:if is used.

/ / normal < view wx: if = "{{something = = = 'foo'}}" class = "foo" > / / occasionally is not normal, <view class="bar" wx:if="{{something == 'bar'} "> <view class="bar" wx:if="{{something == 'bar'} ">

Therefore, it is generally recommended to write the condition first and then add other attributes, or to use the block tag as the condition.

3.8 Page inherits from Component, but extends the Page’s unique config configuration and unique Page life cycle functions. So Component is basically the same as Page, but Component doesn’t have an onLoad life cycle.

4. This and the built-in method

4.1 When updating data, use this.foo = bar directly instead of WeChat’s native this.setData method.

4.2 After modifying data in all possible places where asynchronism may occur, the dirty data checking process should be manually triggered, otherwise page rerendering will not be triggered. Common places are update after request, setTimeout, getStorageSync, etc

5. canvas & base64

Canvas related operation is the same as WeChat native, just refer to here:

ArrayBuffer and Base64 interturn:

These two APIs are available from V1.1.0 (2017.03.31) and can be used directly:

wx.arrayBufferToBase64
wx.base64ToArrayBuffer

6. Other suggestions for development

6.1 Instant APIs defined inside applets all start with $, so we should not start with $when naming, in order to distinguish.

6.2 Also, if Redux is used, the method that connects to it will also be accessed via this.methods.fn(). The recommendation should also be well distinguished, such as binding the methods in the page and component. Like this:

// Redux Action
this.methods.function();

// Page Methods
this.methods.bindFunction();

Some useful Snippets written in development

Cross page communication

This is the applet’s native code, used to update the Data value in the previous page

For example, if you have a page of a form class, one of the fields can be edited by clicking to another full-screen screen

After the change is saved, it will go back to the current page to continue editing other fields

<Array> let crtPage = getCurrentPages(); <Object> let prevPage = crtPage[crtPage. Length - 2]; // Set the data prevPage.setData({note: this.value}) on the previous page; /* * This works for setting the Data on the previous page, * but if the Data on that page is used as Props to the component * * the value in the component will not be updated to the new value */

Regular parses the city string for the WeChat native province selection component

Because the back end of a project is saved with a value like “Shanghai Shanghai Xuhui District”

But the component of WeChat uses an array of values like [‘ Shanghai ‘, ‘Shanghai ‘,’ Xuhui ‘]

So to make sure that when I change it, I’m going to display what I set the last time

/* * Parse String to Wechat City Array * * @param: * City <String>: * * @return: Parse to Wechat City Array * * @param: * City <String>: * * @return: * const parseRegion = (city) = BBL {let STR = city; let region = []; Let reg = [/ \ [^ S province | | city area] + [province] | | city area /, / \ S [^ city | area] + [city | area] /, / \ S [^ | | area county city] + [city] | | area county /,]; for (let r of reg) { const rs = r.exec(str); if (rs ! == null) { region.push(rs[0]); str = str.replace(rs[0], ''); } } return region; };

URL parameter serialization

Purpose: When the small program needs column cutting operation, temporarily save the incoming parameters

// onLoad(op) { this.op = op; } // Relaunch when url = some-url + '? ' + this.serializer(this.op) serializer = (data = {}) => ( Object.entries(data).map( ([key, value]) => ( value ! == undefined ? `${key}=${encodeURIComponent(value)}` : '' ) ) .filter((item) => (item)) .join('&') );