由于最近刚入职新公司,然后前任前端封装了一个子组件,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定义为对象,改变对象中的值不会触发报错,页面也能正常渲染、更新。但是如果你对数据流不是很清楚,还是别这么做了。