Socket
Socket
Sign inDemoInstall

wechat-mini-program-extend

Package Overview
Dependencies
0
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

wechat-mini-program-extend

小程序扩展框架,依赖开发者工具的 npm 构建。具体详情可查阅[官方 npm 文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)。 基础库版本 >= 2.9.5,建议最新。


Version published
Maintainers
1
Weekly downloads
1

Weekly downloads

Readme

Source

wechat-mini-program-extend

小程序扩展框架,依赖开发者工具的 npm 构建。
具体详情可查阅官方 npm 文档。 基础库版本 >= 2.9.5,建议最新。

logo

使用说明

安装

npm install wechat-mini-program-extend

引入

import { PageEx, ComponentEx } from "wechat-mini-program-extend";

或者

import { PageEx, ComponentEx } from "wechat-mini-program-extend/index";

  • 页面扩展接口,替换 Page

PageEx (Object object)

  • 组件扩展接口,替换 Component

ComponentEx (Object object)

基本使用

使用PageEx接口替换Page,指定如下的页面:

PageEx({
  data: {
    num: 114514
  }
});

小程序通过setData函数修改状态,例如修改状态num

this.setData({ num: 1919810 });

使用扩展接口,可简化为赋值形式:

this.data.num = 1919810;

也可以把data引用省略掉:

this.num = 1919810;

在页面中可以直接观察出效果:

<view>{{num}}</view>

在访问状态时,可以把data引用省略掉:

console.log(this.data.num);
console.log(this.num);

通常情况下使用Page / Component 原生接口,要使用到扩展特性的时候,只需要把接口替换为PageEx / ComponentEx 即可。


小程序生命周期

Component.created > Page.created
                  > Page.attached = PageEx.beforeMount
                  > Component.attached = ComponentEx.beforeMount
                  > Component.relations
                  > Page.onLoad
                  > Page.onShow
                  > Component.lifetimes.show or ComponentEx.onShow
                  > ComponentEx.mounted = Component.ready = ComponentEx.onReady
                  > PageEx.mounted
                  > Page.onReady
  • 组件树内Component触发顺序。
    A(parent)B(child)
    A.attached > B.attached > relations.child(A,B) > relations.parent(A,B)
  • onShow onHide / pageLifetimes.show pageLifetimes.hide 互斥,不要同时配置。
  • 如果关闭掉开发工具的模拟器,Page.onReady不会触发,但Page.onShow会触发,再次打开模拟器,Page.onReady触发。

API

选项 / 数据

  • data

    使用Object类型在接口回退(PageExPage)时不会有影响。

    🔴 示例:

    PageEx({
      data: {
        a: 100
      }
    });
    

    🔴 使用Function定义初始数据:

    PageEx({
      props: {
        a: {
          type: Number,
          default: 100
        }
      },
      data() {
        return {
          b: this.a * 2
        };
      }
    });
    

  • props

    同小程序properties选项,选项名称使用props或者properties皆可,只是遵守小程序的定义规范方便接口回退。

    🔴 使用扩展接口时,下面两种定义是等效的:

    PageEx({
      properties: {
        a: {
          type: Number,
          value: 100
        },
        b: {
          type: Number,
          default: 200
        }
      }
    })
    
    PageEx({
      props: {
        a: {
          type: Number,
          default: 100
        },
        b: {
          type: Number,
          default: 200
        }
      }
    })
    

    🔴 默认值default支持Function类型:

    PageEx({
      props: {
        a: {
          type: Number,
          value: 100
        },
        b: {
          type: Number,
          default: 200
        },
        c: {
          type: Number,
          default() {
            return this.a + this.b;
          }
        }
      }
    });
    

    小程序的properties只对Component生效,框架对其扩展到了PageEx接口上。 当页面启动参数与propsproperty匹配时,小程序会在页面初始化时把启动参数的值注入到propsproperty中。注入参数的类型不要超出小程序的处理范围,例如不要意图传入Object类型。

    🔴 示例,访问页面pages/index/index?a=1919810

    PageEx({
      props: {
        a: {
          type: Number,
          value: 100
        }
      },
      onLoad(options) {
        // this.setData({a:options.a}); // 不再需要
          
        console.log(this.a); // 1919810
      }
    })
    

  • computed

    需要注意的是,当用于计算标签样式style时,返回值请务必转为String,小程序只认识字符串。

    🔴 示例:

    PageEx({
        data: {
            color: 'red',
            num: 100
        },
        computed: {
            numStyle() {
                const styles = [`color:${this.color}`];
                return styles.join(";");
            },
            classes() {
                const classes = ["class1", "class2"];
                return classes.join(" ");
            }
        }
    });
    

    WXML:

    <view style="{{numStyle}}">{{num}}</view>
    

    请确保状态会被命中,分支判定可能会丢失跟踪,导致计算属性不更新。

🔴 示例:

PageEx({
    data: {
        feedBack: false, 
        validateStatus: ""
    },
    computed: {
        validateStatusIcon() {
            // 提前读取状态,确保状态被跟踪
            const validateStatus = this.validateStatus;
            if(this.feedBack){
                // feedBack 初始值为 false 时,this.validateStatus 不会被读取
                // return `${this.validateStatus}.svg`;
                return `${validateStatus}.svg`;
            }
            return "";
        }
    }
});
  • methods

    🔴 methods选项扩展到了PageEx接口中,可以把方法定义在methods中。

    PageEx({
      onLoad() {
        this.print('onLoad');
      },
      mounted() {
        this.print('mounted');
      },
      methods: {
        print(lifecycle) {
          console.log(lifecycle);
        }
      }
    });
    

  • watch

    侦听器字段定义仅包含点运算符和标识符,例如监听数组的第一个元素arr[0],正确的格式为"arr.0",注意不要和小程序observers混淆。

    🔴 深度监听(deep = true)适用于引用类型(ObjectArray)。引用类型非深度监听情况下,只有引用变化才会触发回调,就是需要整个对象替换掉,而深度监听则需要进行深度比对,计算量会比较大。

    监听引用类型,可以无脑加上deep = true,监听基本类型可以也加上deep = true,只是会增加无意义的计算量。

      PageEx({
        data: {
          arr: [{ num: 114 }],
          arr2: [{ num: 1919 }]
        },
        watch: {
          'arr.0': function (newVal, oldVal) {
            console.log(`arr ${JSON.stringify(oldVal)} => ${JSON.stringify(newVal)}`);
          },
          'arr.0.num': function (newVal, oldVal) {
            console.log(`arr[0].num ${JSON.stringify(oldVal)} => ${JSON.stringify(newVal)}`);
          },
          'arr2': {
            handler: function (newVal, oldVal) {
              console.log(`arr2 ${JSON.stringify(oldVal)} => ${JSON.stringify(newVal)}`);
            },
            deep: true
          }
        },
        mounted() {
          this.arr[0].num = 514;
          this.arr2[0].num = 810;
        }
      });
    

    输出:

    arr[0].num 114 => 514
    arr2 [{"num":1919}] => [{"num":810}]
    

    🔴 指定immediate = true,侦听器初始化时会触发一次回调。

    PageEx({
      props: {
        num: {
          type: Number,
          value: 114
        }
      },
      watch: {
        num: {
          handler: 'numHandler',
          immediate: true
        }
      },
      methods: {
        numHandler(newVal) {
          console.log(`num = ${JSON.stringify(newVal)}`);
        }
      },
      created() {
        console.log('created');
      },
      mounted() {
        console.log('mounted');
      },
      onLoad() {
        console.log('onLoad');
      }
    });
    

    输出:

    created
    num = 114
    onLoad
    mounted
    

实例 property

  • $data

    🔴 代理组件内部状态访问。

    PageEx({
      props: {
        a: {
          type: Number,
          value: 114
        }
      },
      data() {
        return {
          b: 514
        };
      },
      mounted() {
        console.log(this.$data);
        this.$data.b = 1919810;
      }
    });
    

  • $props

    🔴 代理组件外部状态访问,而实际上小程序会将properties同步到data中。

    PageEx({
      props: {
        a: {
          type: Number,
          value: 114
        }
      },
      data() {
        return {
          b: 514
        };
      },
      mounted() {
        console.log(this.$props);
        this.$props.a = 114514;
      }
    });
    

  • $options

    返回非接口内建保留字的字段,mounteddata等框架内建的保留字会被排除。

    不要定义Function类型字段,页面接口会将Function合并到methods中。

    🔴 可以看作为静态字段,初始化时可能会有用。

    function createOptions(customNum) {
      return {
        customOption: 'custom data',
        customNum,
        props: {
          str: {
            type: String,
            default() {
              return this.$options.customOption;
            }
          }
        },
        data() {
          return {
            num: this.$options.customNum * 2
          };
        }
      };
    }
    
    PageEx(createOptions(57257));
    

  • $root

    指向当前组件所处的Page实例。


  • $parent

    指向父组件或页面。 小程序relations执行在attached回调之后,在mountedonReadyready生命周期中进行首次访问。
    mounted执行前默认绑定Page,任何时候可以向页面发送事件。


  • $children

    与当前实例有直接关系的子组件,$children不保证任何方式顺序的排列。 在readyonReadyonLoadmounted中获取。


选项 / 组合

  • relations

    🔴 该配置通常用不上,$parent$children不完整,应避免在回调中使用。

// behaviors.js 导出
const ParentBehavior = Behavior({});
const ChildBehavior = Behavior({});

// 子组件
ComponentEx({
  behaviors: [ChildBehavior],
  relations: {
    'getParent': {
      type: 'parent',
      target: ParentBehavior,
      linked: function (target, key) {
        console.log(key); // getParent
      },
      unlinked: function (target, key) {

      }
    }
  }
});

// 父组件
ComponentEx({
  behaviors: [ParentBehavior],
  relations: {
    'getChild': {
      type: 'child',
      target: ChildBehavior,
      linked: function (target, key) {
        console.log(key); // getChild
      },
      unlinked: function (target, key) {

      }
    }
  }
});
  • mixins

    🔴 主要用于混入生命周期或数据,方法每一次重定义都会覆盖上一次定义。

  const Mixin = {
  data: {
    b: 200
  },
  methods: {
    test() {
      console.log('test');
    }
  },
  mounted() {
    console.log('mounted 1');
  }
};

PageEx({
  mixins: [Mixin],
  data: {
    a: 100
  },
  methods: {
    test() {
      console.log(this.a + this.b);
    }
  },
  mounted() {
    this.test();
  }
});

输出

mounted 1
300
  • 全局混入

    app.js注入。

import {Extension} from "wechat-mini-program-extend";

Extension.mixin({
  methods: {
    getUserInfo() {
      console.log('114514')
    }
  }
});

App({
  onLaunch(options) {
    // ...
  }
});

实例方法 / 数据

  • $watch

    🔴 注册一个数据侦听器,并返回一个取消侦听的函数。

    PageEx({
      data() {
        return {
          m: {
            n: 1000
          }
        }
      },
      async mounted() {
        const unwatch = this.$watch('m.n', function (val, oldVal) {
          console.log(`${oldVal} => ${val}`);
          if (val >= 3000) {
            unwatch();
          }
        });
        await this.change();
        await this.change();
        await this.change();
      },
      methods: {
        async change() {
          this.m.n += 1000;
          return new Promise(resolve => {
            setTimeout(resolve, 1000);
          });
        }
      }
    });
    

  • $set

    🔴 添加对象属性。

    this.$set(this.m, 'n', 300);
    this.$set(this.arr, '1', 200);
    

  • $delete

    🔴 删除对象属性。

    this.$delete(this.m, 'n');
    this.$delete(this.arr, '1');
    

实例方法 / 总线

避免频繁使用$parrent,$children进行数据交互。
事件总线为框架内建通讯机制,与小程序的事件机制无直接关系。

  • $emit

    🔴 以自身为起点,祖先组件为终点的方向(冒泡顺序)触发一个总线事件,冒泡事件可被拦截。

    this.$emit('event', `来自${this.is}组件`);
    

  • $on

    🔴 注册一个事件监听器。

    this.$on('event', (e) => {
    	console.log(e.data);
    });
    

    🔴 拦截其他事件处理器。

    this.$on('event', (e) => {
    	e.handled = true;
    });
    

  • $off

    🔴 注销事件监听器。

    this.$off('event', callback);
    
    • 如果没有提供参数,则移除所有的事件监听器;
    • 如果只提供了事件,则移除该事件所有的监听器;
    • 如果同时提供了事件与回调,则只移除这个回调的监听器。

  • $once

    🔴 注册一个事件监听器,触发一次后自动注销。

    this.$once('event', (e) => {
    	console.log(e.data);
    });
    

  • $dispatch

    🔴 以祖先组件为起点,自身为终点的方向(捕获顺序)触发一个总线事件,捕获事件可被拦截。页面使用PageEx构建,使事件可以从页面往下传递。

    this.$dispatch('event', `来自${this.is}组件`);
    

  • $broadcast

    🔴 向自身有直接或间接关联的组件发送事件,通常情况下接收目标为页面内除自身外所有组件,广播事件不可被拦截。

    this.$broadcast('broadcast', `来自${this.is}组件`);
    

状态管理模式

接口标准移植自Vuex,可参考Vuex文档。

基本使用

🔴 state一般建议使用函数定义,如果多个状态管理共用一套配置会产生不可预料的冲突。

import { createStore } from "wechat-mini-program-extend/store";

const store = createStore({
    state() {
        return {
            count: 0
        };
    },
    mutations: {
        increment(state) {
            state.count++;
        }
    },
    actions: {
        increment({commit}) {
            commit('increment');
        }
    }
});

export default store; // 导出 src/store/index.js
import { ComponentEx } from "wechat-mini-program-extend";
import store from "path/store"; // 引入 store

ComponentEx({
    computed: {
        count: () => store.state.count
    },
    increment() {
        store.state.count++;
    }
});
<view>
    <text>{{ count }}</text>
    <view>
        <button bind:tap="increment">increment</button>
    </view>
</view>

组件绑定辅助函数

App对象中配置全局容器store,全局容器会挂载到组件的$store属性。

// app.js
import store from "path/store";

App({
    store,
    onLaunch() {
        // ...
    },
    globalData: {
        // ...
    }
});
import {mapActions} from "wechat-mini-program-extend/store";

ComponentEx({
    methods: {
        ...mapActions(["increment"])
    }
})

Keywords

FAQs

Last updated on 12 May 2022

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc