本文作者:DurkBlue

关于vue的父组件与子组件的通信

DurkBlue2021-12-2842288
关于vue的父组件与子组件的通信摘要: uniapp中父组件向子组件传递prop时,如果prop是对象,对象内部不能包含function属性例子如下father.vue<template>  &nb...

uniapp中父组件向子组件传递prop时,如果prop是对象,对象内部不能包含function属性

例子如下


father.vue

<template>

    <view class="uni-container">

<child :fatherData="fatherData" :fatherFcuntion="fatherFcuntion" :fatherMethod="fatherMethod"></child>

</view>

</template>

<script>

import child from './child.vue'

export default {

        components: {

child

        },

        data() {

            return {

fatherData: {

a: 1,

b: {

isShow: function() {

console.log("data定义对象属性函数");

}

}

},

fatherFcuntion: function() {

console.log("data定义函数变量");

},

}

},

methods: {

fatherMethod() {

console.log("method的定义函数");

},

}

}

</script>

child.vue

<template>

<view>

child

</view>

</template>


<script>

export default({

name: "child",

props: {

fatherData: {

type: Object,

default: function() {

return {};

}

},

fatherFunction: {

type: Function,

default: function() {

return function() {}

}

},

fatherMethod: {

type: Function,

default: function() {

return function() {}

}

}

},

mounted() {

console.log("父组件data定义的变量包含函数", this.fatherData);

console.log("父组件data定义的函数变量", this.fatherFunction);

console.log("父组件method定义的函数", this.fatherMethod);

}

})

</script>

结果


![在这里插入图片描述](https://img-blog.csdnimg.cn/20200702173033111.png

可以看到展示数据

1.data定义的变量包含函数,函数属性直接被删除了

2.data定义的函数变量,可以正常传递

3.method定义的函数,可以正常传递

总结:uniapp的prop传递的变量为对象时,对象内部含有函数属性,该函数属性会直接被删除

Vue中的测试截图


Vue中是可以正常传递


原因

uniapp中父组件进行初始化时,会经过


initMixin(Vue);

stateMixin(Vue);

eventsMixin(Vue);

lifecycleMixin(Vue);

renderMixin(Vue);

在initMixIn(Vue)中会执行


function initMixin (Vue) {

  Vue.prototype._init = function (options) {

  .......

if (vm.$options.el) {

      vm.$mount(vm.$options.el);

    }

  };

_init方法中的$mount函数如下


// public mount method

Vue.prototype.$mount = function(

    el ,

    hydrating 

) {

    return mountComponent$1(this, el, hydrating)

};

mountComponent$1函数如下,会new Watcher,函数为updateComponent,函数updateComponent会执行_update


function mountComponent$1(

  vm,

  el,

  hydrating

) {

  ..........

  var updateComponent = function () {

    vm._update(vm._render(), hydrating);

  };


  // we set this to vm._watcher inside the watcher's constructor

  // since the watcher's initial patch may call $forceUpdate (e.g. inside child

  // component's mounted hook), which relies on vm._watcher being already defined

  new Watcher(vm, updateComponent, noop, {

    before: function before() {

      if (vm._isMounted && !vm._isDestroyed) {

        callHook(vm, 'beforeUpdate');

      }

    }

  }, true /* isRenderWatcher */);

  hydrating = false;

  return vm

}

在lifecycleMixin函数内部会定义一个_update属性函数


Vue.prototype._update = function (vnode, hydrating) {

    .......

    if (!prevVnode) {

      // initial render

      vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);

    } else {

      // updates

      vm.$el = vm.__patch__(prevVnode, vnode);

    }

    ......

  };

_update函数中有一个__patch__函数,主要比较newData与oldData的差异进行差量更新


var patch = function(oldVnode, vnode) {

  ............

  if (this.mpType === 'page' || this.mpType === 'component') {

    var mpInstance = this.$scope;

    var data = Object.create(null);

    try {

      data = cloneWithData(this);

    } catch (err) {

      console.error(err);

    }

    data.__webviewId__ = mpInstance.data.__webviewId__;

    var mpData = Object.create(null);

    Object.keys(data).forEach(function (key) { //仅同步 data 中有的数据

      mpData[key] = mpInstance.data[key];

    });

    var diffData = this.$shouldDiffData === false ? data : diff(data, mpData);

    ..........

};


上述有一个cloneWithData方法,最后会返回深度克隆的值,但是该方法会有问题,丢失value值为function的key,并且可能存在循环依赖问题。


function cloneWithData(vm) {

  .....

  return JSON.parse(JSON.stringify(ret))

}

此篇文章由DurkBlue发布,请自觉转载请注明来处
文章投稿或转载声明

来源:DurkBlue版权归原作者所有,转载请保留出处。本站文章发布于 2021-12-28
温馨提示:文章内容系作者个人观点,不代表DurkBlue博客对其观点赞同或支持。

赞(1)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享