关于vue父子组件的传值问题

210 阅读2分钟

在vue中,父组件通过props将值传给子组件,形成单向数据流。

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。来自vue文档

但是,考虑到一些场景,我们需要子组件进行修改父组件的值。应该怎么做呢?

有以下种情况:

1、我们需要修改传过来的值,但是不用修改源数据。

2、我们需要修改传过来的值,同时修改源数据。(类似双向绑定)

这两种情况,官方文档里面都有说明。我就不再赘述。

我接下来要说的事,你们千万别害怕。

我发现:

当父组件用基本数据类型当做props传过去,子组件试图修改,会有问题。

但是,当父组件用对象传值过去,子组件试图修改对象中的值,成功。

talk is cheap

//父组件
<template>
  <input-text
    :input-value.sync="fatherInputValue"
    :origin-data="formData"
  />
</template>

<script>
import InputText from './components/InputText.vue'
export default {
  name: 'passvalue',
  components: {
    InputText
  },
  props: {},
  data() {
    return {
      fatherInputValue: '',
      formData: {
        inputValue: ''
      }
    }
  },
}
</script>
//子组件
<template>
   <input
    :value="inputValue"
    @input="$emit('update:input-value', $event.target.value)"
  />
  <input type="text" v-model="originData.inputValue" />
</template>

<script>
export default {
  name: 'InputText',
  components: {},
  props: {
    inputValue: {
      type: String,
      default: ''
    },
    originData: {
      type: Object,
      default: () => {
        return {
          inputValue: ''
        }
      }
    }
  },
}
</script>

说好的子组件直接不能修改父组件的值呢,这就让人很疑惑。

不过可以归可以,还是不建议这么做,理由还是官方文档所说的,数据修改来源不清晰。

至于为啥呢,我一开始也不清楚,直到今天我看到了vue3.0的说明,在@vue/reactivity中有shallowReadonly这样一个函数。该函数的目的是定义浅只读数据,这意味着深层次的对象值是可以被修改的。并且:在Vue内部中,props就是使用shallowReadonly()函数来定义的。

那是否意味着,上述现象的产生是因为这个原因呢,让我去看看具体代码再谈。

有大佬知道原因可留言解惑。