在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>

 

Logo

前往低代码交流专区

更多推荐