解决方式一:
- 在data对象中创建一个值,如visible
- 使用watch监听props属性中对应的值 ,如value,
- watch 赋予data副本 来同步组件外对props的修改,始终保持data中的值等于父组件传递过来的值
- 当data中的值变化时,触发父组件的自定义事件
// 子组件
<template>
<div class="modal" v-show="visible">
<p>我是子组件</p>
<button @click="cancel">子组件的关闭按钮</button>
</div>
</template>
<script>
export default {
name: "MyList",
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
visible: false
}
},
watch: {
value(val) {
this.visible = val;
}
},
methods: {
cancel() {
this.visible = false;
this.$emit('modalVisibleChange', false);
}
},
};
</script>
//父组件
<template>
<div>
<p>我是父组件</p>
<button v-show="!isShow" @click="isShow=true">父组件的显示按钮</button>
<MyList :value="isShow" @modalVisibleChange="modalVisibleChange"/>
</div>
</template>
<script>
import MyList from './MyList'
export default {
name: "app",
data() {
return {
isShow: false
};
},
components: {
MyList,
},
methods: {
modalVisibleChange(val) {
this.isShow = val;
}
}
};
</script>
优点:解决了 父子组件之间props 双向绑定的问题;
缺点: 在父级调用 子组件的时候,还需要写一个 modalVisibleChange 的方法,而且子组件还需要写方法控制组件的显示和隐藏,代码过于冗长,且难以理解。
解决方式二:通过.sync
<template>
<div class="modal" v-show="value">
<p>我是子组件</p>
<button @click="cancel">子组件的关闭按钮</button>
</div>
</template>
<script>
export default {
name: "MyList",
props: {
value: {
type: Boolean,
default: false
}
},
methods: {
cancel() {
this.$emit('update:value', false) // $emit触发父组件数据同步修改
}
},
};
</script>
// 父组件
<template>
<div>
<p>我是父组件</p>
<button v-show="!isShow" @click="isShow=true">父组件的显示按钮</button>
<MyList :value.sync="isShow"/>
</div>
</template>
<script>
import MyList from './List'
export default {
name: "app",
data() {
return {
isShow: false
};
},
components: {
MyList,
},
};
</script>
解决方式三:(推荐)
- 使用 v-model 实现组件props的双向绑定
// modal组件
<template>
<div class="modal" v-show="value">
<div class="close" @click="cancel">X</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default:false
}
},
methods:{
cancel(){
this.$emit('input', false);
}
},
}
</script>
// 父组件调用modal组件
<modal v-model="isShow"></modal>
export default {
name: 'app',
data () {
return {
isShow:true
}
}
}
</script>