【问题标题】:Vue.js - One-way data binding updating parent from childVue.js - 从子级更新父级的单向数据绑定
【发布时间】:2017-09-12 14:12:59
【问题描述】:

鉴于冒号表示 VueJS2 中的单向数据绑定,我想了解为什么在此示例中,子级能够更新在父级中声明并通过 prop 传递给子级的数组(单向)。

https://jsfiddle.net/ecgxykrt/

<script src="https://unpkg.com/vue"></script>

<div id="app">
    <span>Parent value: {{ dataTest }}</span>
    <test :datatest="dataTest" />
</div>

var test = {
    props: ['datatest'],
    mounted: function() {
        this.datatest.push(10)
    },
    render: function() {}
}

new Vue({
    el: '#app',
    components: {
        'test': test
    },
    data: function() {
        return {
            dataTest: []
        }
    }
})

提前致谢!

【问题讨论】:

  • 我对答案很感兴趣,因为如此公平的答案无法解释这一点。并且 vue 明确声明这是一种单向绑定,您甚至应该在直接改变 prop 时收到警告。
  • @Stephan-v 对象和数组通过引用传递。您可以像修改 const 值一样修改它们。你不能做的就是将 prop 更改为一个全新的对象或数组。

标签: javascript vue.js vuejs2


【解决方案1】:

Vue 阻止您分配给道具。它不会阻止您调用道具的方法或修改其元素或成员,任何这些都可以更改对象的内容。这些都不会改变 prop 本身的值,它是对底层结构的引用。

一个相关的问题是Vue cannot detect changes to Array elements or additions/deletions of Object members

更多here.

【讨论】:

  • 这如何解释为什么孩子能够更新父数据?
  • 这些注意事项也完全不同,因为长度本身没有直接修改,并且项目已经提前设置。据此,push 也应该被正确跟踪。 vuejs.org/v2/guide/list.html#Mutation-Methods
  • 子节点获得对数组的引用,因此能够修改其内容。这与导致警告的情况完全相同。它与修改长度无关,也与项目是预先创建的事实无关。核心问题是 Object 是一个引用。
  • 因此,由于我更改了父级已更新的子注入道具对象的属性,因此此行为破坏了“单向”绑定,对吗?我需要做些什么来避免这种情况?创建一个对象或数组的每个道具的深层副本?
  • 如果你想修改本地数据项,是的,做一个深拷贝。然后使用数据项。正确处理取决于您要完成的工作。我不会说对每个道具都进行深度复制;很多情况下你不需要修改。
【解决方案2】:

如果您愿意,您可以通过创建浅拷贝并将其分配给子项中的新数据项来避免这种情况。

https://jsfiddle.net/6xxba1fz/

var test = {
  props: ['test'],
  data: function() {
  return {
    myTest: this.test.slice()
  }
  },
  mounted: function() {
    this.myTest.push(10)
  },
  render: function() {}
}

new Vue({
  el: '#app',
  components: {
    'test': test
  },
  data: function() {
    return {
      dataTest: []
    }
  }
})

【讨论】:

  • 如果我想创建对象的浅拷贝,而不是数组,是否需要使用外部库进行深拷贝?
  • 如果我使用 Lodash 克隆一个 vuejs 的 observable 对象,即使在克隆中引用也是相同的,所以这不会解决我的问题 =(。在这种情况下我需要做什么做什么?
  • 你可以使用 Object.assign。 childData = Object.assign({}, parentProp);
【解决方案3】:

请避免使用某些名称作为键和值

:datatest="dataTest" 方法错误

:data-test="dataTest" 更好的方式(使用 Kabab 案例)

HTML

<div id="app">
  <span>Parent value: {{ dataTest }}</span>
  <test :data-test="dataTest" />
</div>

JS

var test = {
  props: {
        dataTest:{
        type:Number
      }
  },
  mounted: function() {
    this.datatest.push(10)
  },
  render: function() {}
}

new Vue({
  el: '#app',
  components: {
    'test': test
  },
  data: function() {
    return {
      dataTest: []
    }
  }
})

结果:

父值:[]

【讨论】:

  • 你推送到datatest而不是dataTest。如果您检查控制台,这将导致错误,您当然会保留空数组。
  • 这个答案应该只是OP中的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
  • 2019-02-22
  • 1970-01-01
  • 2021-05-21
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多