Vue.js 为什么Vue在不发出事件的情况下更改子级的父级值

Vue.js 为什么Vue在不发出事件的情况下更改子级的父级值,vue.js,Vue.js,我是Vue的新手,但这种行为是否与道具的设计完全矛盾 我通过使用Object.assign({},this.test\u对象)成功地阻止了它初始化子组件中的值时,但这不应该是默认行为吗 以下是一些背景 我试图在一个大得多的应用程序中设置脏状态(例如,值已更改,因此用户必须在继续前进之前将数据保存回数据库) 我有一个事件被父组件发出并捕获,但我必须测试值并初始化脏状态的代码没有运行,因为父组件中的值已经更改 Vue.component('parent component'{ 模板:“#父组件”,

我是Vue的新手,但这种行为是否与道具的设计完全矛盾

我通过使用
Object.assign({},this.test\u对象)成功地阻止了它初始化子组件中的值时,但这不应该是默认行为吗

以下是一些背景

我试图在一个大得多的应用程序中设置脏状态(例如,值已更改,因此用户必须在继续前进之前将数据保存回数据库)

我有一个事件被父组件发出并捕获,但我必须测试值并初始化脏状态的代码没有运行,因为父组件中的值已经更改

Vue.component('parent component'{
模板:“#父组件”,
数据:函数(){
返回{
测试对象:{
val:'测试值'
}
}
}
});
Vue.component('子组件'{
模板:“#子组件”,
道具:{
测试对象:对象
},
数据:函数(){
返回{
子对象:this.test\u对象
}
}
});
Vue.config.productionTip=false;
新Vue({
el:“#应用程序”,
});

这在父组件中

testObject.val={{{testObject.val}}

HTML输入
使用
v型
是一件非常具有欺骗性的事情。如果不小心,最终可能会修改不属于组件的数据。在您的情况下,您意外地将只读道具直接传递到
v-model
。它不知道它是
prop
还是本地组件状态

您所做的是正确的解决方案,但考虑到单向/单向数据流,我们可以以更明确和优雅的方式重写此示例:

您的组件定义将是:

Vue.component( 'parent-component', {
  template: '#parent-component',
  data: function() {
    return {
      testObject: {
        val: 'Test Value'
      }
    }
  },

  methods: {
    // Added this method to listen for input event changes
    onChange(newValue) {
      this.testObject.val = newValue;

      // Or if you favor immutability
      // this.testObject = {
      //   ...this.testObject,
      //   val: newValue
      // };
    }
  }
});
您的模板应该是:

<script type="text/x-template" id="parent-component">
  <div>
    <child-component :test_object="testObject"
      @inputChange="onChange"></child-component>

    <p>This is in the parent component</p>
    <p><code>testObject.val = {{testObject.val}}</code></p>

  </div>
</script>

<!-- Instead of v-model, you can use :value and @input binding. -->
<script type="text/x-template" id="child-component">
  <div>
    <label for="html_input">HTML Input</label>
    <input type="text" name="html_input"
      :value="test_object.val"
      @input="$emit('inputChange', $event.target.value)" />
  </div>
</script>
需要注意的关键事项:

  • 使用v-model时,请确保严格处理组件的本地值/数据。决不能引用外部道具的副本
  • 如果您接受当前值作为
    :值作为
    道具,接受事件作为
    @input
    ,则类似于自定义表单的组件可以轻松转换为可与
    v-model
    一起使用的组件<代码>v型
    将仅显示
  • 对该值的任何修改都应发生在同一组件中

使用
v-model
是一件非常具有欺骗性的事情。如果不小心,最终可能会修改不属于组件的数据。在您的情况下,您意外地将只读道具直接传递到
v-model
。它不知道它是
prop
还是本地组件状态

您所做的是正确的解决方案,但考虑到单向/单向数据流,我们可以以更明确和优雅的方式重写此示例:

您的组件定义将是:

Vue.component( 'parent-component', {
  template: '#parent-component',
  data: function() {
    return {
      testObject: {
        val: 'Test Value'
      }
    }
  },

  methods: {
    // Added this method to listen for input event changes
    onChange(newValue) {
      this.testObject.val = newValue;

      // Or if you favor immutability
      // this.testObject = {
      //   ...this.testObject,
      //   val: newValue
      // };
    }
  }
});
您的模板应该是:

<script type="text/x-template" id="parent-component">
  <div>
    <child-component :test_object="testObject"
      @inputChange="onChange"></child-component>

    <p>This is in the parent component</p>
    <p><code>testObject.val = {{testObject.val}}</code></p>

  </div>
</script>

<!-- Instead of v-model, you can use :value and @input binding. -->
<script type="text/x-template" id="child-component">
  <div>
    <label for="html_input">HTML Input</label>
    <input type="text" name="html_input"
      :value="test_object.val"
      @input="$emit('inputChange', $event.target.value)" />
  </div>
</script>
需要注意的关键事项:

  • 使用v-model时,请确保严格处理组件的本地值/数据。决不能引用外部道具的副本
  • 如果您接受当前值作为
    :值作为
    道具,接受事件作为
    @input
    ,则类似于自定义表单的组件可以轻松转换为可与
    v-model
    一起使用的组件<代码>v型
    将仅显示
  • 对该值的任何修改都应发生在同一组件中

感谢@HarshalPatil的解释,那么您是说用
object.assign({},this.test\u对象)初始化子对象是创建不会从当前组件中变异的本地对象的正确方法吗?@BenCasey,绝对不是<代码>对象。分配
在当前情况下有效,但不是一个很好的通用解决方案。很多事情都会出错。想象一下,
testObject
是一个异步值。你最终会为这个道具设置观察者
testObject
可以进行深度嵌套,以此类推。我建议的一种是单向数据体系结构的通用模式。它适用于Vue、React、Angular、Elm等。感谢@HarshalPatil的解释,您是说用
object.assign({},this.test_对象)初始化子对象是创建不会从当前组件中变异的本地对象的正确方法吗?@BenCasey,绝对不是<代码>对象。分配
在当前情况下有效,但不是一个很好的通用解决方案。很多事情都会出错。想象一下,
testObject
是一个异步值。你最终会为这个道具设置观察者
testObject
可以进行深度嵌套,以此类推。我建议的一种是单向数据体系结构的通用模式。它适用于Vue、React、Angular、Elm等。