vue2.0父子组件通信

xiaoxiao2021-02-28  13

因为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 來源:简书
转载请注明原文地址: https://www.6miu.com/read-2595483.html

最新回复(0)