Uni如何桥接小程序的

uni编译后的代码

const getEmitter = (function () {
  let Emitter;
  return function getUniEmitter() {
    if (!Emitter) {
      Emitter = new Vue();
    }
    return Emitter;
  };
})();

function apply(ctx, method, args) {
  return ctx[method].apply(ctx, args);
}

function $on() {
  return apply(getEmitter(), "$on", [...arguments]);
}
function $off() {
  return apply(getEmitter(), "$off", [...arguments]);
}
function $once() {
  return apply(getEmitter(), "$once", [...arguments]);
}
function $emit() {
  return apply(getEmitter(), "$emit", [...arguments]);
}
uni连接vue和小程序的桥梁
function initProperties(props, isBehavior = false, file = "") {
  const properties = {};
  if (!isBehavior) {
    properties.vueId = {
      type: String,
      value: "",
    };
    // 用于字节跳动小程序模拟抽象节点
    properties.generic = {
      type: Object,
      value: null,
    };
    properties.vueSlots = {
      // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
      type: null,
      value: [],
      observer(newVal, oldVal) {
        const $slots = Object.create(null);
        newVal.forEach((slotName) => {
          $slots[slotName] = true;
        });
        this.setData({//调用小程序的setData
          $slots,
        });
      },
    };
  }
  if (Array.isArray(props)) {
    // ['title']
    props.forEach((key) => {
      properties[key] = {
        type: null,
        observer: createObserver(key),
      };
    });
  } else if (isPlainObject(props)) {
    // {title:{type:String,default:''},content:String}
    Object.keys(props).forEach((key) => {
      const opts = props[key];
      if (isPlainObject(opts)) {
        // title:{type:String,default:''}
        let value = opts.default;
        if (isFn(value)) {
          value = value();
        }

        opts.type = parsePropType(key, opts.type);

        properties[key] = {
          type: PROP_TYPES.indexOf(opts.type) !== -1 ? opts.type : null,
          value,
          observer: createObserver(key),
        };
      } else {
        // content:String
        const type = parsePropType(key, opts);
        properties[key] = {
          type: PROP_TYPES.indexOf(type) !== -1 ? type : null,
          observer: createObserver(key),
        };
      }
    });
  }
  return properties;
}
uni创建页面和组件
//小程序的component https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html
function createPage(vuePageOptions) {
  {
    return Component(parsePage(vuePageOptions));
  }
}

function createComponent(vueOptions) {
  {
    return Component(parseComponent(vueOptions));
  }
}
uni创建App
function createApp(vm) {
  App(parseApp(vm));//小程序的App方法https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html
  return vm;
}

function parseApp(vm) {
  return parseBaseApp(vm, {
    mocks,
    initRefs,
  });
}

const hooks = [
  "onShow",
  "onHide",
  "onError",
  "onPageNotFound",
  "onThemeChange",
  "onUnhandledRejection",
];

function parseBaseApp(vm, { mocks, initRefs }) {
  initEventChannel();
  {
    initScopedSlotsParams();
  }
  if (vm.$options.store) {
    Vue.prototype.$store = vm.$options.store;//挂在store
  }

  Vue.prototype.mpHost = "mp-weixin";

  Vue.mixin({
    beforeCreate() {
      if (!this.$options.mpType) {
        return;
      }

      this.mpType = this.$options.mpType;

      this.$mp = {
        data: {},
        [this.mpType]: this.$options.mpInstance,
      };

      this.$scope = this.$options.mpInstance;

      delete this.$options.mpType;
      delete this.$options.mpInstance;
      if (this.mpType === "page" && typeof getApp === "function") {
        // hack vue-i18n
        const app = getApp();
        if (app.$vm && app.$vm.$i18n) {
          this._i18n = app.$vm.$i18n;
        }
      }
      if (this.mpType !== "app") {
        initRefs(this);
        initMocks(this, mocks);
      }
    },
  });

  const appOptions = {
    onLaunch(args) {//这里定义了onLaunch,其他在hooks中
      if (this.$vm) {
        // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前
        return;
      }
      {
        if (wx.canIUse && !wx.canIUse("nextTick")) {
          // 事实 上2.2.3 即可,简单使用 2.3.0 的 nextTick 判断
          console.error(
            "当前微信基础库版本过低,请将 微信开发者工具-详情-项目设置-调试基础库版本 更换为`2.3.0`以上"
          );
        }
      }

      this.$vm = vm;

      this.$vm.$mp = {
        app: this,
      };

      this.$vm.$scope = this;
      // vm 上也挂载 globalData
      this.$vm.globalData = this.globalData;

      this.$vm._isMounted = true;
      this.$vm.__call_hook("mounted", args);

      this.$vm.__call_hook("onLaunch", args);
    },
  };

  // 兼容旧版本 globalData
  appOptions.globalData = vm.$options.globalData || {};
  // 将 methods 中的方法挂在 getApp() 中
  const { methods } = vm.$options;
  if (methods) {
    Object.keys(methods).forEach((name) => {
      appOptions[name] = methods[name];
    });
  }

  initHooks(appOptions, hooks);

  return appOptions;
}