vue.js子组件修改父组件传进来的props

我在做仿饿了吗vue的项目,其中ratingselect模块的要修改food模块传进来的props值

我是这么做的:
food父模块:
html

<ratingselect :select-type="selectType" :only-content="onlyContent" :desc="desc" :ratings="food.ratings"></ratingselect>

js

eventBus.$on('ratingtype.select', (type) => {
    this.selectType = type;
    this.$nextTick(() => {
        this.scroll.refresh();
    });
});
 eventBus.$on('content.toggle', (onlyContent) => {
    this.onlyContent = onlyContent;
    this.$nextTick(() => {
         this.scroll.refresh();
    });
});

ratingselect子模块
html

<div class="ratingselect">
    <div class="rating-type">
        <span @click="select(2,$event)" class="block positive" :class="{'active':selectType===2}">{{desc.all}}<span class="count">{{ratings.length}}</span></span>
        <span @click="select(0,$event)" class="block positive" :class="{'active':selectType===0}">{{desc.positive}}<span class="count">{{positives.length}}</span></span>
        <span @click="select(1,$event)" class="block negative" :class="{'active':selectType===1}">{{desc.negative}}<span class="count">{{negatives.length}}</span></span>
    </div>
    <div @click="toggleContent" class="switch" :class="{'on':onlyContent}">
        <span class="icon-check_circle"></span>
        <span class="text">只看有内容的评价</span>
    </div>
</div>

js

    methods: {
        select(type, event) {
            if (!event._constructed) {
                return;
            }
            this.selectType = type;
            eventBus.$emit('ratingtype.select', type);
        },
        toggleContent(event) {
            if (!event._constructed) {
                return;
            }
            this.onlyContent = !this.onlyContent;
            eventBus.$emit('content.toggle', this.onlyContent);
        }
    }

实现是可以实现,但是vue2.0不允许子组件修改父组件的传值,怕子组件污染父组件,造成不可控。所以求解决方法

这是报错:

clipboard.png

阅读 12.8k
6 个回答

通过子组件$emit发射一个方法,在父组件使用子组件的地方用v-on绑定这个自定义事件,然后在父组件定义这个方法,虽然这种方式可以修改父组件数据,但是官方是不推荐在组件内修改通过props传入的父组件数据,而是推荐使用vuex

可以通过$emit向父组件发送一个事件,父组件监听事件对数据进行修改。在vue2.3新增了.sync修饰符,会自动帮你绑定一个update事件,也就是说使用.sync之后,你只需要子组件中需要修改的地方$emit一个update:prop的事件就可以了

没看到子组件有用Props定义父组件传递的数据验证。先抛开这个不说
子组件通过$emit发送事件到父组件.也没见你父组件有定义接受事件

<ratingselect :select-type="selectType" :only-content="onlyContent" :desc="desc" :ratings="food.ratings"></ratingselect>

还有子组件是不允许修改父组件的值.但是传过来的值就是独立的 没有耦合性的
这一切都不符合vue框架的规则.所以不报错才大头鬼.建议题主多看看vue的官方文档

selectType和onlyContent已经$emit在父组件修改了,子组件为毛还要赋值

子组件data里定义一个变量等于父组件的selectType,操作这个变量。

我做的好复杂,哈哈,还没开始用vuex。
做法这样的:
父组件传值子组件,prop属性传递
子组件传值父组件,$emit传递
另外:子组件想要修改自己定义的prop怎么办,$emit值到父组件,由父组件绑定的prop来修改
父组件:

v-bind:resourceTypeId="resource.resourcesTypeId" 
v-on:selResourceType="setResourceType"

子组件:

data () {
    return {
        selResourceModel: '请选择资源类型'
    }
}
<Select v-model="selResourceModel" @on-change="selResourceType" placeholder="请选择资源类型" clearable style="width:250px">
    <Option v-for="item in resourcestypeList" :key="item.id" :value="item.id">{{ item.displayName }}</Option>
</Select>
props: [
  "resourceTypeId"
],

这里为什么没有在子组件直接v-model绑定props的resourceTypeId,因为这样的话,选择Select项目的话,值就要改变了prop的值是不允许在子组件改变的,那么就只能重新定义一个,属性selResourceModel,然后监控属性props:resourceTypeId,一旦修改就重新设置
selResourceModel这样就解决了

selResourceType () {
    this.$emit("selResourceType", this.selResourceModel)
}
watch: {
    resourceTypeId: function (newTypeId) {
        this.selResourceModel = newTypeId
    }
},
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题