How to Mix in WeChat Mini Programs: Custom Component Behavior

Thoughts on Refactoring

Recently, when refactoring a small program, I found that many pages use the function of positioning and reverse geoanalysis, so almost every page in the project has to write the relevant logic of obtaining positioning, which is really a big headache. Is there a way to extract this part of the logic? Written as a Component is too large, because we only need js related logic. It is not the best solution to extract the method into utils and then call it, and it is necessary to declare a responsive data to receive. Can the applet be mixed in? The answer is: yes!

Behaviors in applets

Behaviors are features for code sharing between components, similar to "mixins" or "traits" in some programming languages.

Each behavior can contain a set of properties, data, lifecycle functions and methods. When a component ( note: the basic library 2.9.2 also supports the use of behaviors in the page ) references it, its properties, data and methods will be merged into the component, and the life cycle function will also be called at the corresponding time. Each component can refer to multiple behaviors, and behaviors can also refer to other behaviors.
behavior needs to be defined using the Behavior() constructor.

reference documents

Behavior(Object object)
registers a behavior and accepts a parameter of type Object.

definition section type Is it required? describe
properties Object Map no properties of the same component
data Object no Data from the same component
methods Object no Same method as custom component
behaviors String Array no Introducing other behaviors
created Function no life cycle function
attached Function no life cycle function
ready Function no life cycle function
moved Function no life cycle function
detached Function no life cycle function

example

// /behaviors/location.js

let QQMapWX = require('../utils/qqmap-wx-jssdk.min.js');
let qqmapsdk = new QQMapWX({
    
    key: '你自己的key'});
module.exports = Behavior({
    
    
    // 共享数据
    data: {
    
    
        location: {
    
    }
    },

    methods: {
    
    
        getLocation() {
    
    
        	// 因为我们的业务功能必须在位置信息获取到以后才能正常使用,所以这里封装成Promise,以便链式调用
            return new Promise((resolve, reject) => {
    
    
                wx.authorize({
    
    scope: 'scope.userLocation'}).then(() => {
    
    
                    this.handleLocation(resolve, reject)
                }).catch(err => {
    
    
                    wx.showModal({
    
    
                        title: '提示',
                        content: '获取不到您的定位,请允许使用您的定位,以获取准确服务地点',
                        success: (res) => {
    
     
                            if (res.confirm) {
    
    
                                wx.openSetting().then(() => {
    
    this.handleLocation(resolve, reject)})
                            }
                        }
                    })
                })
            })
        },
        handleLocation(resolve, reject) {
    
    
            wx.getLocation({
    
    type: 'gcj02'}).then(res => {
    
    
                const {
    
     latitude, longitude } = res
                this.setData({
    
     latitude, longitude })
                wx.setStorageSync('latitude', latitude);
                wx.setStorageSync('longitude', longitude);
                this.turnLocationToAddress(resolve, reject);
            }).catch(() => {
    
    
                wx.showToast({
    
    
                    title: '请前往手机设置允许微信使用定位信息',
                    icon: 'none',
                    mask: true
                })
                reject()
            })
        },
        turnLocationToAddress(resolve, reject) {
    
    
            const {
    
     latitude, longitude } = this.data
            qqmapsdk.reverseGeocoder({
    
    
                location: {
    
    
                  latitude: latitude,
                  longitude: longitude
                },
                success: (res) => {
    
    
                    if (res.status === 0) {
    
    
                        let {
    
    province, city, district} = res.result.address_component;
                        let adCode = res.result.ad_info.adcode;
                        let location = {
    
    
                            'longitude': longitude,
                            'latitude': latitude,
                            'province': province,
                            'city': city,
                            'district': district,
                            'address': res.result.address,
                            'districtId': adCode
                        };
                        this.setData({
    
     location });
                        wx.setStorageSync('location', JSON.stringify(location));
                        resolve(location)
                    }
                },
                fail: function (err) {
    
    
                    reject()
                    console.log('位置解析失败:', err);
                }
            });
        }
    }
})

// page

const LocationBehavior = require('../../behaviors/location');
Page({
    
    
  behaviors: [LocationBehavior],
  data: {
    
    },
  onLoad: function () {
    
    
  	// getLocation是LocationBehavior中的方法
    this.getLocation().then(() => {
    
    
        this.getDetail()
    })
  }
})

In the page, we can also get the user's location information through this.data.location.

Overriding and combining rules for fields with the same name

A component and its referenced behavior can contain fields with the same name, and the processing methods for these fields are as follows:

  • If there are properties or methods with the same name:

    1. If the component itself has this property or method, the property or method of the component will override the property or method of the same name in the behavior;
    2. If the component itself does not have this property or method, the property or method of the later behavior defined in the component's behaviors field will override the previous property or method of the same name;
    3. On the basis of 2, if there is a nested reference behavior, the rule is: the referencer behavior overrides the property or method with the same name in the referenced behavior.
  • If there is a data field (data) with the same name:

    • If the data fields with the same name are all object types, object merging will be performed;
    • In other cases, the data will be overwritten, and the overwriting rules are: referrer behavior > cited behavior, later behavior > front behavior. (The one with the higher priority overrides the one with the lower priority, and the largest one is the highest priority)
      The life cycle functions will not overwrite each other, but will be called one by one at the corresponding triggering time:
  • For different life cycle functions, follow the execution order of component life cycle functions;

    • For the same type of life cycle functions, follow the following rules:
      1. behavior takes precedence over component execution;
      2. The referenced behavior takes precedence over the referrer's behavior;
      3. Front behaviors are executed prior to later behaviors;
    • If the same behavior is referenced multiple times by a component, the lifecycle functions it defines will only be executed once.

Official documents are the best learning materials: WeChat Mini Program Development Documentation - Custom Component Behavior

Guess you like

Origin blog.csdn.net/weixin_43867717/article/details/124060527