在Vue2中组件的props的数据流动改为了只能单向流动,即只能由组件外(调用组件方)通过组件的DOM属性attribute传递props给组件内,组件内只能被动接收组件外传递过来的数据,并且在组件内,不能修改由外层传来的props数据。
prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
也就是说:废弃了props的双向绑定,虽然对于整个项目整体而言是有利且正确的,但是在某些时候我们确实需要从组件内部修改props的需求。
案例:
定义一个开关组件:
//开关组件代码
Vue.component("switchbtn",{
template:"<div @click='change'>{{result?'开':'关'}}</div>",
props:["result"],
methods:{
change(){
this.result=!this.result;
}
}
});
引用 :
<div id="app">
<!--开关组件-->
<switchbtn :result="result"></switchbtn>
<!--外部控制-->
<input type="button" value="change" @click="change">
</div>
//调用组件
new Vue({
el: "#app",
data:{
result:true//开关状态数据
},
methods:{
change(){
this.result=!this.result;
}
}
});
但是在vue2.0中上面的代码在点击开关时会报错:
[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: "result" (found in component )
组件内不能修改props的值,同时修改的值也不会同步到组件外层,即调用组件方不知道组件内部当前的状态是什么。
那么如何双向绑定状态呢?
Vue父子组件传值通过props和$emit,父组件传来一个result,这个只在子组件中用props注册,虽然在子组件中不能直接修改,但是自组建可以通过$emit通知父组件修改,在子组件中定义一个sonReault:this.result,我们只需要通过观察者模式监听result 和 sonReault:
data() {
sonRedsult: this.result
},
watch: {
result (val) {
this.myResult = val
},
sonResult(val) {
this.$emit('toFather',val)
}
}