Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-

由于最近刚入职新公司,然后前任前端封装了一个子组件,select框的,为啥也没有使用this.$emit()方法,也没有使用@change的方法,子组件下拉框改变了,父组件里面的值 跟着改变,下面来看看我自己做的demo

父组件

<template>
    <div>
           <KSelect :dataList="datas" :list="list"></KSelect>
           <button @click="login">登录</button>
    </div>
</template>
<script>
import KSelect from './KSelect'
export default {
    data() {
        return {
            datas:[
                {value:'',label:'全部'},
                {value:'1',label:'vue'},
                {value:'2',label:'css'},
                {value:'3',label:'js'},
                {value:'4',label:'react'},
                {value:'5',label:'html'}
            ],
           list:''
        }
    },
    methods: {
        login(){
            console.log('this.list',this.list)
        }
    },
    components:{
        KSelect
    }
}
</script>

子组件 KSelect

<template>
  <div>
      <select v-model="list"> 
        <option :value ="item.value" v-for="(item,index) in dataList" :key="index">{{item.label}}</option>
      </select>
  </div>
</template>

<script>
export default {
    props:{
        dataList:{
            type:Array,
            default: () => []
        },
        list:{
            type:String,
            default:''
        }
    },
    data(){
        return{
            
        }
    }
}
</script>

如果select是使用v-model,并且list是个字符串,我们点击下拉框切换选项
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
当我们点击react时,在点击登录会提示这个报错,而且父组件list的值没有改变,因为vue是 单向数据流的,当在子组件要改变父组件传进去的值,会提示这个报错,如果我把list改成一个对象传进去就行了,我们看看下面的改造

父组件

<template>
    <div>
           <KSelect :dataList="datas" :list="list"></KSelect>
           <button @click="login">登录</button>
    </div>
</template>
<script>
import KSelect from './KSelect'
export default {
    data() {
        return {
            datas:[
                {value:'',label:'全部'},
                {value:'1',label:'vue'},
                {value:'2',label:'css'},
                {value:'3',label:'js'},
                {value:'4',label:'react'},
                {value:'5',label:'html'}
            ],
           list:{selectValue:''}
        }
    },
    methods: {
        login(){
            console.log('this.list',this.list)
        }
    },
    components:{
        KSelect
    }
}
</script>

子组件 KSelect

<template>
  <div>
      <select v-model="list.selectValue"> 
        <option :value ="item.value" v-for="(item,index) in dataList" :key="index">{{item.label}}</option>
      </select>
  </div>
</template>

<script>
export default {
    props:{
        dataList:{
            type:Array,
            default: () => []
        },
        list:{
            type:Object,
            default: () => {}
        }
    },
}
</script>

在这里插入图片描述
点击react后在点击登录,看看控制台
在这里插入图片描述
这样就进行对父组件里面的值做改变了

今天下午想了两个小时,然后才知道原来是用了这种方法,不过,当props是对象的时候,子组件直接修改数据,不会引起警告。但还是不建议这样做……

按官方文档中的设计讲,父子组件中的数据流是单向的, 同时也给出了子组件操作数据时的解决方法。

1 用 $emit(‘update:xxx’) 改变。这种方式并没有改变单向数据流的特性
2 将prop定义为对象,改变对象中的值不会触发报错,页面也能正常渲染、更新。但是如果你对数据流不是很清楚,还是别这么做了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值