Author: Sun Mengge

Recently, I participated in the development of the company’s first small program. The development experience is basically similar to webView-based hybrid development, which can call the official powerful API, but there are some pits or unaccustomed places. This article documents some of the issues during development from a practical point of view:

1. Style priorities are out of order

When using the Button component, we find that setting width in the class does not work, so paste the following code:

.my-button{
  width: 140rpx;
  height: 60rpx;
  line-height: 60rpx;
  padding: 0;
}
Copy the code

After the investigation of wechat debugging tool, we found that the style priority of user Agent was actually higher than the style class we wrote ourselves, which is basically impossible to happen in the browser

The solution is actually quite simple, add width! Style =”width:140rpx” style=”width:140rpx”

Plus! After important, the actual effect of the width is in line with our expectations, but the wechat debugging tool still shows the user Agent style first, which should be a bug of the debugging tool.

2. Encapsulation of common UI components, cumbersome parameter definition

Basic components in UI visuals, such as buttons, have a specific style: background color/font, for example. Using the Component function of the applet to encapsulate the Component, writing the default style and receiving the class passed in from the outside can facilitate subsequent development.

The React with < tag {… Props}> this is a way for the component to receive props and pass it through to the next component, but this is not supported by the widget.

This means that we need to list all the parameters supported by button components in properties:

properties: {
    classes: {
      type: String,
      value: '',
    },
    type: {
      type: String,
      value: 'default',
    },
    plain: {
      type: Boolean,
      value: false,
    },
    size: {
      type: String,
      value: 'default',
    },
    ......
  },
Copy the code

3. Global style picker*Be disabled

*{
  box-sizing: border-box;
}
Copy the code

The code above will report an error at compile time because the applet disables such a selector. Hazard a guess as to why: this kind of wide-scope selector conflicts with the style isolation of custom components?

So how do you add a global style to an applet? You’ll have to manually write all the labels you need, but there’s a code available online:

view,scroll-view,swiper,swiper-item,movable-area,movable-view,cover-view,cover-image,icon,text,rich-text,progress,button,checkbox-group,checkbox,form.input.label,picker,picker-view,radio-group,radio,slider,switch,textarea,navigator,functional-page-navigator,image,video,camera,live-player,live-pusher,map,canvas,open-data,web-view,ad{
  box-sizing: border-box;
}
Copy the code

4. Custom component, bind:tap called twice

When wrapping basic components, such as button, the following should be avoided:

onTap(e) {
  if (!this.data.disabled && !this.data.loading) {
    this.triggerEvent('tap', e.detail)
  }
},
Copy the code
<button bindtap="onTap"></button>
Copy the code

This encapsulated component fires two TAP events, one by the applet itself and one by a triggerEvent.

You can use a non-built-in event type, such as click:

onTap(e) {
  if (!this.data.disabled && !this.data.loading) {
    this.triggerEvent('click', e.detail)
  }
},
Copy the code

Preventing the TAP event from bubbling can also be addressed:

<button catchtap="onTap"></button>
Copy the code

5. Use Boolean() for type conversion in WXML

For example, in a component, listen for a String argument and display the text label if it is not empty, otherwise not:

// player.wxml
<text class="text1" wx:if="{{ Boolean(leftText) }}">{{ leftText }}</text>
Copy the code
// index.wxml
<player leftText="Van read"></player>
Copy the code

In this way, the leftText field is obviously passed, but the text tag is still not displayed.

// player.wxml
<text class="text1" wx:if="{{ leftText }}">{{ leftText }}</text>
Copy the code

That’s right. That’s what we want.

Amazing, isn’t it?

6. The onTimeUpdate callback is invalid after the InnerAudioContext calls seek

The InnerAudioContext is used to play the audio and is passed the onTimeUpdate callback to get the current playback progress.

But onTimeUpdate is no longer called when the call to seek jumps to play at the specified position.

In fact, many people in the small program community have already mentioned this problem. After about one and a half years, the wechat team has not been able to fix it, and can only temporarily use a compromise to fix it. The solution is actually very simple:

progressOnChange(e) {
  if (this.properties.src && this.data.innerAudioContext) {
    const innerAudioContext = this.data.innerAudioContext;
    innerAudioContext.pause();
    innerAudioContext.seek(innerAudioContext.duration * e.detail.value / 100);
    setTimeout(() = > {
      innerAudioContext.play();
    }, 500); }},Copy the code

Pause the play first, then execute seek, and then set a delay of about 500ms to call play.

Problem with the time when InnerAudioContext obtains duration

If you want to get duration before the audio starts to play, you can’t get duration before the audio starts to play.

innerAudioContext.onCanplay(() = > {
  setTimeout(() = > {
    this.setData({
      durationStr: secondToTimeStr(innerAudioContext.duration) || '- : -}); },500);
});
Copy the code

Regardless of how many milliseconds is appropriate for a setTimeout setting, it does not work on a real machine.

So use onTimeUpdate honestly:

innerAudioContext.onTimeUpdate(() = > {
  this.setData({
    durationStr: secondToTimeStr(innerAudioContext.duration) || '- : -})});Copy the code

If you find it too costly to evaluate every onTimeUpdate, you can do it yourself.

8. Set the background color

There is a backgroundColor field in the json file of the current page, but it is invalid after setting. Later, it is found that this field does not represent the backgroundColor of the visible area, but the backgroundColor of the window when the page is pulled down.

If you need to set the background color of the page, you can set the style of the page TAB:

page{
  background: #f9fafb;
}
Copy the code

To be updated…