众所周知,v-model可以实现数据双向的绑定,我们也知道v-model其实就是一个由属性和事件组成的语法糖,如下表:
元素类型 | 属性 | 事件 |
---|---|---|
input[type=text]、textarea | value | input |
input[checkbox]、input[radio] | checked | change |
select | value | change |
同时我们也知道父子组件可以使用props和$emit进行通信,那我们的父子组件是否可以通过v-model配合$emit来进行组件间的通信呢?当然可以,我们来实现一个自定义的弹窗组件,先上效果图
打开窗口之前:
点击按钮弹窗效果:
上源码:
父组件
<template>
<div id="app">
<el-button @click="openModel">open</el-button>
<model v-model="flag"> 我是一个自定义组件</model>
</div>
</template>
<script>
import model from './../src/compontents/Model'
export default {
name: 'App',
data(){
return {
flag:false,
}
},
components:{
model
},
methods:{
openModel(){
this.flag = true
}
}
};
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
margin:0;
height: 100%;
width: 100%;
/* min-height: 800px; */
}
</style>
子组件
<template>
<div v-if="value" class="panel">
<div class="model">
<div class="model-title">我是一个没有感情的title</div>
<div class="model-content">
<slot></slot>
</div>
<div class="model-footer">
<el-button @click="closeModel">关闭</el-button>
</div>
</div>
</div>
</template>
<script>
export default {
props:{
value:{
type :Boolean,
default: false
}
},
watch:{
value(val){
console.log(111,val)
}
},
methods:{
closeModel(){
this.$emit('input', false)
}
}
}
</script>
<style scoped>
.panel{
position: fixed;
top:0;
left: 0;
bottom: 0;
right: 0;
background-color: #eee;
}
.model{
width: 600px;
height: 400px;
border: 1px solid #ccc;
padding:20px;
box-sizing: border-box;
margin: 10px auto;
background-color: #fff;
}
.model-title{
border-bottom: 1px solid #ccc;
padding-bottom: 10px;
text-align: left;
font-weight: 600;
}
.model-content{
height: 260px;
padding:20px;
}
.model-footer{
border-top: 1px solid #ccc;
padding-top: 10px;
text-align: right;
font-weight: 600;
}
</style>
撒花🎉完成
或许你还有疑问,我们$emit回去的方法名称,是否只能有input和change呢?我们可以区了解一下model这个属性,好了,快乐时间过的特别快,又是时间说拜拜了