webpack学习:uni运行时代码解读三 (页面和组件交互)

prop传值给组件

// 页面的wxml,aa是组件 tabs是页面传给aa的prop,除此之外还会传过来一个vue-id的prop
// 还会绑定一个__l方法,在子组件的attached钩子内部会触发来建议vue实例之间的父子关系
<aa vue-id="8dd740cc-1" tabs="{{tabs}}" bind:__l="__l"></aa>

// 组件的js 第一节的componentOptions中
attached () {
    // 在这里可以获取到自身的data和prop传过来的值,
    const properties = this.properties;

    const options = {
      mpType: isPage.call(this) ? 'page' : 'component',
      mpInstance: this,
      propsData: properties
    };
    // 把prop的vueid赋值给mp上
    initVueIds(properties.vueId, this);

    // 处理父子关系,利用向页面触发的__l方法,让父mp的里的vm挂载到options里的parent属性上
    initRelation.call(this, {
      vuePid: this._$vuePid,
      vueOptions: options
    });

    // 初始化 vue 实例
    this.$vm = new VueComponent(options);
    // 触发首次 setData
    this.$vm.$mount();
  }

vue的$ref是如何实现的

// 页面的wxml vue的很简单 <aa ref="fe"/>,注意vue-ref和data-ref
<aa class="vue-ref" vue-id="8dd740cc-1" data-ref="fe" bind:__l="__l"></aa>
// js 代码简单清晰,对vm的$refs做了一个代理,利用vm的selectAllComponents功能配合页面上的data-ref和“vue-ref”这个class来实现
function initRefs (vm) {
  const mpInstance = vm.$scope;
  Object.defineProperty(vm, '$refs', {
    get () {
      const $refs = {};
      selectAllComponents(mpInstance, '.vue-ref', $refs);
      // TODO 暂不考虑 for 中的 scoped
      const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for');
      forComponents.forEach(component => {
        const ref = component.dataset.ref;
        if (!$refs[ref]) {
          $refs[ref] = [];
        }
        $refs[ref].push(component.$vm || component);
      });
      return $refs
    }
  });
}

vue的$children是如何实现的

// 上文提到的这里把父vm设置在parent属性上,然后实例化的时候,uni改了vue的源码
initRelation.call(this, {
      vuePid: this._$vuePid,
      vueOptions: options
    });

this.$vm = new VueComponent(options);

// 源码如下
function initLifecycle (vm) {
  var options = vm.$options;

  // locate first non-abstract parent
  var parent = options.parent;
  if (parent && !options.abstract) {
    while (parent.$options.abstract && parent.$parent) {
      parent = parent.$parent;
    }
    parent.$children.push(vm);
  }
  vm.$parent = parent;
}
posted @ 2022-01-10 23:07  爱吃巧克力的狗  阅读(134)  评论(0编辑  收藏  举报