[vue warning] avoid mutating a prop directly
一、问题描述

使用props,通过父组件给子组件传值,子组件在使用props中的属性时,直接对props中的属性进行了修改。修改方式为直接对props中的属性赋值,或者使用双向绑定。
父组件代码:

<categroy :course="item" />

子组件代码:

<template>
  <div class="course-list">
    <dl class="categroy-dl">
      <dt>类别</dt>
      <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="不限" name="不限"></el-tab-pane>
        <el-tab-pane label="C语言" name="C语言"></el-tab-pane>
        <el-tab-pane label="Java" name="Java"></el-tab-pane>
        <el-tab-pane label="Python" name="Python"></el-tab-pane>
      </el-tabs>
    </dl>
  </div>
</template>
<script>
export default {
  props: {
    activeName: {
      type: String,
      default: "不限"
    }
  },
  methods: {
    handleClick(tab, event) {
      console.log(tab, event);
      this.$emit("queryCoures", this.activeName);
    }
  }
};

此时会抛出警告:vue.runtime.esm.js?2b0e:619 [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: “activeName”. activeName 为Props中的一个属性名。

二、解决方法

通过警告的提示信息可知,在子组件中不可以对父组件通过props传过来的属性进行修改。我们可以使用data或者计算属性转接一下。如果需要同步修改父组件中的值,则需使用$emit调用父组件中的方法对其进行修改。
更改后子组件代码:

<template>
  <div class="course-list">
    <dl class="categroy-dl">
      <dt>类别</dt>
      <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="不限" name="不限"></el-tab-pane>
        <el-tab-pane label="C语言" name="C语言"></el-tab-pane>
        <el-tab-pane label="Java" name="Java"></el-tab-pane>
        <el-tab-pane label="Python" name="Python"></el-tab-pane>
      </el-tabs>
    </dl>
  </div>
</template>
<script>
export default {
  props: {
    categroy: {
      type: String,
      default: "不限"
    }
  },
  data() {
      // categroy不与el-tabs直接双向动态绑定,而是使用categroy为activeName赋初始值,activeName与el-tabs双向动态绑定
    return { activeName: this.categroy };
  },
  methods: {
    handleClick(tab, event) {
      console.log(tab, event);
      // 使用$emit调用父组件的方法,同步categroy的值
      this.$emit("queryCoures", this.activeName);
    }
  }
};
三、总结

在vue2中,直接修改prop是被视作反模式的。由于在新的渲染机制中,每当父组件重新渲染时,子组件都会被覆盖,所以应该把props看做是不可变对象。–参考文档

子组件不可直接修改props中的属性,应该emit一个事件给父组件,让父组件去处理修改。应遵守父子组件之间的传值规范。

Logo

前往低代码交流专区

更多推荐