使用vue2.0,props双向改变数据。

使用了element ui。看文档可以用$on与$emit模拟双向绑定。但是似乎失败了。。两天了没解决,心好累。。

  1. 组件代码

   <el-col :span="5">
        <el-select v-model="provinceValue" placeholder="请选择" filterable @change="testChange">
            <el-option
                    v-for="item in provinceOptions"
                    :label="item.label"
                    :value="item.value">
            </el-option>
        </el-select>
    </el-col>

methods: {
    testChange(val){
                this.$emit('testChange',val);
            }
}
   

2.父级代码

<vue-address :provinceValue=provinceValue
                      :cityValue=cityValue
                      @testChange="testChange2">
</vue-address> 

import vueAddress from 'src/components/address'

components: {
        vueAddress
      },
data: function() {
        return {
            provinceValue:'全国',
            cityValue:''
        }
      },
methods: {
    testChange2(val){
            this.provinceValue=val;
       }
   }

最后在父级点击组件依旧是

[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: "provinceValue" 
阅读 22.8k
6 个回答

组件代码:
应该这样写

methods: {
    testChange(val){
        this.$emit('testchange',val);
        // 或者
        // this.$emit('test-change',val);
    }
}

父组件:

<vue-address :provinceValue=provinceValue
             :cityValue=cityValue
              @testchange="testChange2">
              // @test-change="testChange2">
</vue-address> 

原因:vue中$emit的写法并不支持驼峰,只能是全部小写,或者在分隔的地方用-

1,组件代码
<el-col :span="5">
    <el-select v-model="provinceValueData" placeholder="请选择" filterable @change="testChange">
        <el-option
            v-for="item in provinceOptions"
            :label="item.label"
            :value="item.value">
        </el-option>
    </el-select>
</el-col>

props: {
    provinceValue: String
}
data () {
    provinceValueData: this.provinceValue
}
watch: {
    provinceValue (val) {
        this.provinceValueData = val
    }
}
methods: {
    testChange(val){
        this.$emit('testChange',val);
    }
}

2.父级代码
<vue-address :provinceValue=provinceValue :cityValue=cityValue @testChange="testChange2">
</vue-address> 

import vueAddress from 'src/components/address'

components: {
    vueAddress
},
data: function() {
    return {
        provinceValue:'全国',
        cityValue:''
    }
},
methods: {
    testChange2(val){
        this.provinceValue=val;
   }
}
新手上路,请多包涵

子组件内不应该用 v-model,因为 v-model 只是一个简化命令,使用 v-model="provinceValue" 相当于
:value="provinceValue" @input="e => provinceValue = e.target.value",所以在你输入值的同时已经直接修改了provinceValue,导致报了那个警告。所以应该拆解开来写。

# 2个方法

第一个 :

// 父组件
<dialog-apply :visible.sync="dialogApplyVisible" />

// 子组件
<el-dialog
      :visible.sync="visible"
      title="申请"
      :before-close="onClose"
>

onClose() {
  this.$emit('update:visible', false)
}

第二个 :

// 父组件
<dialog-apply :visible.sync="dialogApplyVisible" @close='dialogApplyVisible = false' />

// 子组件
<el-dialog
      :visible.sync="visible"
      title="申请"
      :before-close="onClose"
>

onClose() {
  this.$emit('close')
}

这2个方法 , :before-close 是关键 ;

在子组件的方法中,写上$emit('你的子组件内方法'),父组件调用子组件用v-on:子组件方法名字="调用父组件方法"

看报错提示的意思应该是子组件中修改了prop中provinceValue的值
若你想实现prop的双向绑定,可以创建一个自组件的副本,然后watch prop中的provinceValue

推荐问题
宣传栏