vue2.0父子组件通信

因为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: "onlyContent"

解决办法

在子组件data中定义一个父组件传递过来的副本,再把该副本利用this.$emit("event","value")传回父组件,父组件利用自定义事件接受传回的值

子组件

< template >
< div class= "ratingselect" >
< div class= "rating-type" >
< span @ click= "select(2,$event)" class= "block positive" : class= "{'active':selecttype===2}" >
{{desc.all}}
< span class= "count" >47 </ span >
</ span >
< span @ click= "select(0,$event)" class= "block positive" : class= "{'active':selecttype===0}" >
{{desc.positive}}
< span class= "count" >47 </ span >
</ span >
< span @ click= "select(1,$event)" class= "block negative" : class= "{'active':selecttype===1}" >
{{desc.negative}}
< span class= "count" >47 </ span >
</ span >
</ div >
< div @ click= "toggleContent()" class= "switch" : class= "{'on':onlycontent}" >
< span class= "icon-check_circle" ></ span >
< span class= "text" >只看有内容的评价 </ span >
</ div >
</ div >
</ template >
< script >
const POSITIVE = 0;
const NEGATIVE = 1;
const ALL = 2;
export default {
//组件要维护的部分
props:{
//接收ratings,默认返回数组
ratings:{
type: Array,
default(){
return [];
}
},
//接收评论类型,默认选中的是‘全部’
selectType:{
type: Number,
default:ALL
},
//接收是否看有内容的评价状态,默认false
onlyContent:{
type: Boolean,
default: false
},
//接收评论类型
desc:{
type: Object,
default(){
return {
all: '全部',
positive: '满意',
negative: '不满意'
};
}
}
},
data(){
return{
selecttype: this. selectType,
onlycontent: this. onlyContent,
}
},
methods: {
select( type, event){
if(! event. _constructed){
return;
}
/*
由于子组件改了selectType但是父组件不知道,
所以用事件广播来使父组件知道
*/
this. selecttype=type;
this. $emit( 'selectchange', this. selecttype);
},
toggleContent(){
this. onlycontent=! this. onlycontent;
this. $emit( 'onlycontentChange', this. onlycontent);
}
}
}
</ script >

父组件

   
< template >
< transition name= "move" >
< div class= "food" v-show= "showFlag" ref= "foodDom" >
< div class= "food-content" >
< div class= "img-header" >
< img : src= "food.image" >
< div class= "back" @ click= "hide()" >
< i class= "icon-arrow_lift" ></ i >
</ div >
</ div >
< div class= "content" >
< h1 class= "title" >{{food.name}} </ h1 >
< div class= "detail" >
< span class= "sell-count" >月售{{food.sellCount}} </ span >
< span class= "rating" >好评率{{food.rating}}% </ span >
</ div >
< div class= "price" >
< span class= "now" >¥{{food.price}} </ span >
< span class= "old" v-show= "food.oldPrice" >¥{{food.oldPrice}} </ span >
</ div >
< div class= "cartcontrol-wrapper" >
< v-cartcontrol : food= "food" ></ v-cartcontrol >
</ div >
< transition name= "fade" >
< div @ click= "addFirst($event)" class= "addBuy" v-show= "!food.count || food.count === 0" >加入购物车 </ div >
</ transition >
</ div >
< div class= "spilt" v-show= "food.info" ></ div >
< div class= "info" v-show= "food.info" >
< h1 class= "title" >商品介绍 </ h1 >
< p class= "text" >{{food.info}} </ p >
</ div >
< div class= "spilt" v-show= "food.info" ></ div >
< div class= "rating" >
< h1 class= "title" >商品评价 </ h1 >
< v-rating @ onlycontentChange= "changeOnlycontent" @ selectchange= "changeSelect" : selectType= "selectType" : onlyContent= "onlyContent" : desc= "desc" : ratings= "food.ratings" ></ v-rating >
</ div >
</ div >
</ div >
</ transition >
</ template >
< script >
import Vue from 'vue'
import BScroll from 'better-scroll'
import Cartcontrol from '../cartcontrol/cartcontrol.vue'
import Rating from '../rating/rating.vue'
const POSITIVE = 0;
const NEGATIVE = 1;
const ALL = 2;
export default {
data(){
return{
showFlag: false,
selectType:ALL,
onlyContent: false,
desc:{
all: '全部',
positive: '推荐',
negative: '吐槽'
}
}
},
props:{
food:{
type: Object
}
},
components:{
'v-cartcontrol':Cartcontrol,
'v-rating':Rating
},
computed:{
},
methods:{
show(){
this. showFlag = true;
//商品详情组件时初始化状态
this. selectType=ALL;
this. onlyContent= false;
this. $nextTick(() =>{
if(! this. scroll){
this. scroll = new BScroll( this. $refs. foodDom,{click: true})
} else{
this. scroll. refresh();
}
});
},
hide(){
this. showFlag = false;
},
addFirst( event){
if(! event. _constructed){
return;
}
Vue. set( this. food, 'count', 1);
},
changeSelect( val){
this. selectType=val;
},
changeOnlycontent( val){
this. onlyContent=val;
}
}
}
</ script >


作者:BrotherWy
链接:https://www.jianshu.com/p/751440d84d7a
來源:简书

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值