Vue.js中强调了props单向数据流。子组件中不要直接修改props。但是,我在写的时候发现,下面这种方式修改是正常,可以运行的
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
</head>
<body>
<template id="demo">
<div>
<ul>
<li v-for="item in info.list">{{ item }}</li>
</ul>
<button @click="addItem">AddItem</button>
</div>
</template>
<div id="app">
<v-demo :info="info"></v-demo>
</div>
<script type="text/javascript">
Vue.component("v-demo", {
template: "#demo",
props: ["info"],
methods: {
addItem: function () {
this.info.list.push(1);
// this.info = {
// "list": [1,2,3,4,5,6]
// };
}
}
})
var vn = new Vue({
el: "#app",
data: {
"info": {
"list": [1,2,3]
}
}
})
</script>
</body>
</html>
当我直接this.info = ??
时,Vue会警告,不要直接修改props的值。但是,我上面push的方式也算是修改了props的值吧?这样是好的实践吗?
js有数据类型有基本类型和引用类型之分,基本类型是直接赋值,引用类型是的值是指向某个地址的指针。懂了这些,我们再来看你props的东西:this.info = ??你将引用指针改为了值,很明显vue是能检查到的,所以提示了你,props的东西不要在子组件里瞎改。this.info.list.push(1):list是一个复杂数据类型,神仙都不知道你到底在哪个地方该的,因为所有地方的的值只是指向这个list的一个指针,你怎么该list,指针不会变(至于Obeject.defineProperty()没法知道数组变化的问题不在这里提),但是对应的视图为什么会变呢?因为你用了vue变异方法push,一个会主动触发watch、更新视图的玩意(不详解)。回到问题:这是个好实践吗?绝对不是。为了便于数据流追踪(人话:回头你和你的接锅侠能看清楚自己到底写的什么鬼),vue的理念是单向数据流,就是你要改变props传来的值,用$emit告诉father组件,在father里改,这样就做到了单向数据流