首页 > 技术文章 > 将父组件传入子组件的数据,子组件更改后传回父组件,而不会影响单向数据流

wang--chao 2021-10-25 11:41 原文

很多情况下,会将父组件的输入传到子组件,又子组件更改后再传回父组件,比如更改用户信息时,封装组件时。

image
我这里是将formData的数据传入封装好的form组件中
form组件接收props:formData

再将接收到的数据保存在本组件的data() {return {newFormData}}中,直接在data(){return{} }中是拿不到props中的数据的
直接在create周期函数中

created() {
this.newFormData = formData
}

这样也是不行的,要通过下面的方式才能拿到props中父组件传过来的数据

props: {
      formData: {
        type: Object,
        defalut: () => ({})
      }
    },
    data() {
      return {
        newFormData: {}
      }
    },
    created() {
      this.init()
    },
    methods: {
      init() {
        this.newFormData = this.formData
      }
  }

如果直接使用props中的formData就会违背了单向数据流的原则,通过这个方式更改数据,再通过emit将数据传回父组件就不会违背单项数据流的原则

实现双向绑定,不违背单向数据流

更便捷的方式就是使用v-model这样就可以不用在父组件中定义一个函数接收子组件emit发送的方法了

父组件

<div class="userContainer">
    <base-form 
      :formItems='formItems' 
      v-model='formData' 
      :labelWidth='labelWidth'
    >
      <template v-slot:header>
        <div>这是header插槽</div>
      </template>
      <template #footer>
        <el-button type="primary" size="mini" @click="resetHandle">重置</el-button>
        <el-button type="primary" size="mini" @click="searchClick">搜索</el-button>
      </template>
    </base-form>
  </div>

子组件

props: {
      modelValue: {
        type: Object,
        defalut: () => ({})
      }
    },
    data() {
      return {
        formData: {}
      }
    },
    created() {
      // this.init()
    },
    //watch的使用,当formData发生改变,将新的值发送给父组件,从而改变外面formData的值,它的只改变从而处理它改变后的操作
    watch: {
      formData: {
        handler(newValue) {
          this.$emit('update:modelValue', newValue)
        },
        deep: true
      }
    },
    //computed的使用,如果父组件通过v-model绑定给子组件的值modelValue发生改变,则会引起computed中fomrData的就算,将modelValue的值返回给formData,
    // formData依赖的值发生改变,从而改变formData的值,会使用return来改变值
    computed: {
      formData() {
        return this.modelValue
      }
    },
  }

推荐阅读