【问题标题】:Passing the properties of an object as props Vuejs将对象的属性作为道具传递Vuejs
【发布时间】:2018-12-05 20:26:02
【问题描述】:

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

<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-model 覆盖 parentData 时 childDataA 不是“反应性的”。我必须使用“watch”来覆盖“data”,类似于 childDataB

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

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

【问题讨论】:

  • 你为什么不直接使用childPropsA?。 childPropsA 是反应性权利。如果需要进行一些修改,则可以使用计算属性。

标签: javascript vue.js vuejs2


【解决方案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>

【讨论】:

  • 很抱歉打扰您,希望您能再次帮助我。我读了 Linus Borg 的文章,“你的 props 的值是原始类型 - 字符串、数字、布尔值”,“只有对象属性和数组可以”,我不太了解原始类型和计算属性。如果计算属性只是简单的数组或对象,那么我可以将 props 传递给数组或对象,它们将是计算属性,对吧?你能和我分享一些关于他们的文件吗?非常感谢
【解决方案2】:

Watch 只观察确实是反应性的属性。传递对象不会使它们的属性反应。只需将您想要的属性作为道具传递。 使用 Vue.util.extend,你可以强制属性在这种情况下是响应式的。

【讨论】:

    猜你喜欢
    • 2020-01-18
    • 2017-07-22
    • 1970-01-01
    • 2022-11-11
    • 2018-08-10
    • 2021-07-12
    • 1970-01-01
    相关资源
    最近更新 更多