将对象的属性作为道具传递给Vuejs

时间:2018-06-27 03:58:41

标签: javascript vue.js vuejs2

大家好,                                     我有些困惑。我有两个组件(子组件和父组件),并且将对象的属性作为道具传递

<child :child-data="abc" ></child>
Vue.component('childComponent', {
props: ['childData'],
 data: function(){
    return {
        count:this.childData,// recommend use Vue.util.extend
    }
 },
});

Vue将把childComponent的“数据”属性递归转换为getter / setter,以使其“具有响应性”。 那么为什么不将数据自动绑定到模板呢?我读了一些建议使用Vue.util.extend。为什么选择Vue.util.extend?

更新

我的例子: https://jsfiddle.net/hoanghung1995/xncs5qpd/56/

当我设置parentData的默认值时,childDataA将显示它。但是,当我使用v模型来覆盖parentData时,childDataA不会“反应”。我必须使用“监视”来覆盖“数据”,类似于childDataB

Vue.util.extend示例:https://jsfiddle.net/sm4kx7p9/3/

为什么Vue.util.extend可以正常工作但不使用“监视”功能?,

2 个答案:

答案 0 :(得分:1)

要说明后台实际发生的情况,请Linus Borg has as excellent answer for your question。总结一下他的答案,您的方法不起作用的原因是data是一个计算属性,而props被作为原始类型传递。换句话说,data对您的道具进行复制(而不是通过引用传递)。

另一种绕过此方法的方法是将childData声明为计算属性而不是数据,即:

computed: {
    childDataA() {
        return this.childPropsA;
    },
    childDataB() {
        return this.childPropsB;
    }
}

使用computed起作用的原因是因为现在计算出的属性可以监视对其依赖项的更改。

基于原始小提琴的概念验证示例:

Vue.component('child', {
  props: ['childPropsA', 'childPropsB'],
  template: "#sub",
  computed: {
    childDataA() {
      return this.childPropsA;
    },
    childDataB() {
      return this.childPropsB;
    }
  }
});
new Vue({
  el: '#app',
  data: {
    parentData: '123'
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  parentData:{{parentData}}<br>
  <input type="text" v-model="parentData">
  <child :child-props-a="parentData" :child-props-b="parentData"></child>
</div>
<template id="sub">
  <div>
    <p> 1- {{ childDataA }}</p> 
    <p> 2- {{ childDataB }}</p> 
    </div>
</template>

以上方法在功能上与data + watch方法相同,但是我觉得它很麻烦,并在您的代码中添加了不必要的冗长:

data: function() {
    return {
      childDataA: this.childPropsA,
      childDataB: this.childPropsB
    };
  },
  watch: {
    childPropsA() {
      this.childDataA = this.childPropsA;
    },
    childPropsB() {
      this.childDataB = this.childPropsB;
    }
  }

Vue.component('child', {
  props: ['childPropsA', 'childPropsB'],
  template: "#sub",
  data: function() {
    return {
      childDataA: this.childPropsA,
      childDataB: this.childPropsB
    };
  },
  watch: {
    childPropsA() {
      this.childDataA = this.childPropsA;
    },
    childPropsB() {
      this.childDataB = this.childPropsB;
    }
  }
});
new Vue({
  el: '#app',
  data: {
    parentData: '123'
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  parentData:{{parentData}}<br>
  <input type="text" v-model="parentData">
  <child :child-props-a="parentData" :child-props-b="parentData"></child>
</div>
<template id="sub">
  <div>
    <p> 1- {{ childDataA }}</p> 
    <p> 2- {{ childDataB }}</p> 
    </div>
</template>

答案 1 :(得分:0)

Watch仅监视确实具有反应性的属性。传递对象不会使它们的属性具有反应性。只需传递您想要作为道具的属性即可。 使用Vue.util.extend,您可以在这种情况下强制该属性为反应性的。