众所周知props的值在子组件更改会报错,就像这样。
[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: "data"
found in
---> <CcCurrentTime> at src/components/currentTime.vue
<App> at src/App.vue
<Root>
但是有些情况下,子组件把props里面值改了,并没有触发报错信息,导致在不知情的情况下造成了数据污染。比如这样
父组件
<template>
<div id="app">
<CurrentTime :data="data"></CurrentTime>
</div>
</template>
<script>
import CurrentTime from "./components/currentTime.vue";
export default {
name: "App",
components: { CurrentTime },
data: () => {
return {
data: { xx: { xxx: { xxxx: 123 } } },
};
},
};
</script>
子组件
<template>
<div>
<div v-if="sonData">{{ sonData.xx.xxx.xxxx }}</div>
</div>
</template>
<script>
export default {
name: "cc-current-time",
props: {
data: Object,
},
data: () => {
return {
sonData: null,
};
},
mounted() {
this.sonData = this.data;
setTimeout(() => {
this.sonData.xx.xxx.xxxx = 520;
}, 5000);
},
};
</script>
控制台
如果传过来复杂类型就会导致这种情况,那我们想使用这个数据,并且做格式化处理就会造成污染。
产生的原因是props接收到的是数据地址,并不是数据本身,父子变量指向同一个内存地址导致的。
那知道原因解决起来就很简单了。
通过JSON.parse(JSON.stringify())深拷贝或者手写深拷贝方法。
在使用props传值时候尽量保持只传简单类型数据,通过简单类型数据二次获取复杂类型数据。
比如父组件传递数据id,子组件再通过id请求获取数据详细信息。