【Vue】6.解决父组件向子组件传值修改以后再传回父组件的问题

本文探讨了在Vue2.0中如何避免直接修改由父组件传递给子组件的props值,以防止数据同步错误。通过使用data或computed属性创建props副本,确保了组件间数据的正确流动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在vue2.0中父组件向子组件传入一个值,这个值在子组件里面被改变以后再传回父组件,这个时候vue组件会报错:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "dialogShow"

 

在vue2.0中组件的props的数据流动改为了只能单向流动,即只能由组件外(调用组件方)通过组件的DOM属性attribute传递给props组件内,组件内只能被动接收组件外传递过来的数据,并且在组件内,不能修改由外层传来的props数据,组件内不能修改props的值,同时修改的值也不会同步到父组件,父组件不知道子组件内部当前的状态是什么,因为dailogShow不可写,所以需要在data中或者computed中创建一个副本 dailogShow变量,初始值为props属性dailogShow的值,同时在组件内所有需要调用props的地方调用这个data对象。

子组件:Landing001.vue

<template>
  <div v-if="dialogShow" class="dialog-bg">
    <div class="dialog" :class="{'dialog-show':dialogShow}">
      <div class="dialog-title">手机号验证</div>
      <p class="dialog-description">完成手机号验证,可在有信背调公众号登录</p>
      <div class="dialog-form">
        <input class="dialog-form-input" type="text" v-model="mobileCode" placeholder="请输入短信验证码"/>
        <span class="dialog-form-code" @click="getVerificationCode">获取验证码</span>
      </div>
      <div class="dialog-btn">
        <button class="dialog-cancel" @click="cancelDialogBtn">取消</button>
        <button class="dialog-submit" @click="submitDialogBtn">确定</button>
      </div>
    </div>
  </div>
</template>

<script>
    export default {
      props: {
        dialogShow: {
          default: false,
          type: Boolean,
          request: true,
        },
        mobile: {
          default: '',
          type: String,
          request: true,
        },
      },
      data() {
        return {
          mobileCode: '',
          childDialogShow: this.dialogShow,
        };
      },
      created() {
        console.log(`DialogComponent:${this.dialogShow}`);
        console.log(`DialogComponent childDialogShow:${this.childDialogShow}`);
      },
      computed: {
        dialogShowAndCode() {
          return {
            dialogShow: this.childDialogShow,
            code: this.mobileCode,
          };
        },
      },
      methods: {
        getVerificationCode() {
          // console.log(this.userInfo.mobile);
          // todo-jack check mobile number format
        },
        cancelDialogBtn() {
          // this.dialogShow = false; 这里直接修改props里面的值
          // this.$emit('childByValue', this.dialogShow); 传回父组件就会报错
           this.childDialogShow = false;
           this.$emit('childByValue', this.dialogShowAndCode);
        },
        submitDialogBtn() {
          this.childDialogShow = false;
          this.$emit('childByValue', this.dialogShowAndCode);
        },
      },
    };
</script>

父组件:Landing.vue

<template>
  <div id="first">
    <div class="form-btn-submit">
      <button class="btn-submit" @click="userInfoSumit">提交</button>
    </div>
    <dialogcomponent :dialogShow="dialogShow" v-on:childByValue="childByValue"></dialogcomponent>
  </div>
</template>

<script>
  import dialogcomponent from '../../components/DialogComponent.vue';

  export default {
    data() {
      return {
        name: 'landing001',
        dialogShow: false,
      };
    },
    methods: {
      userInfoSumit() {
        this.dialogShow = !this.dialogShow;
      },
      childByValue(childValue) {
        // this.dialogShow = childValue; 报错
         this.dialogShow = childValue.dialogShow;
        console.log(this.dialogShow);
        console.log(childValue.code);
      },
    },
    components: {
      dialogcomponent,
    },
  };
</script>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值