今天在工作遇到了一个小问题,需求是在一个vm实例中创建一个组件,是一个弹框,我使用了组件来做这个弹框.在父组件中有一个按钮点击显示子组件.
当子组件显示的时候,子组件左上角有一个× 点击可以关闭他,一开始我是这么做的:
- 在父组件上定义一个变量,默认为false ,然后使用v-show来控制子组件的显示和隐藏
- 当子组件显示的时候在子组件上定义变量,默认为true,当点击 ×的时候改变这个变量为false
- 最后完成这个组件的显示和关闭
**问题是这样代码的耦合性很高,父组件和子组件的判断逻辑复杂,需要同时控制两个属性,很头疼
那么换另一个思路,在父组件上定义一个属性.用来隐藏和显示这个子组件,用props 来传值,当子组件关闭的时候吧这个属性传回给父组件,由父组件身上的隐藏显示方法去关闭这个子组件!
上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>父子传值</title>
<style>
*{
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="app">
<p>我是父组件</p>
<button @click="showson"> 点击显示子组件</button>
<sonbox @formson="fromsonFn" v-show="ctrlloter" :center="ctrlloter"></sonbox>
</div>
<template id="sonbox">
<div>
<p>我是子组件</p>
<button @click="closeSon">我是在子组件里面的按钮 点击关闭子组件</button>
</div>
</template>
<script src="lib/vue.js"></script>
<script>
var vm =new Vue({
el:'#app',
components:{
'sonbox':{
template:'#sonbox',
props:{
center:Boolean
},
methods:{
closeSon(){
this.$emit('formson',false);
}
}
}
},
data:function(){
return{
ctrlloter:false,
}
},
methods:{
showson(){
this.ctrlloter=true;
},
fromsonFn(val){
this.ctrlloter=val;
}
}
})
</script>
</body>
</html>
父组件传值给子组件的步骤:
1.在父组件中定义属性ctrlloter
2.然后在使用子组件的html元素上 添加绑定属性v-bind: 简写 :
跟上子组件要在自己内部的接收的值代码是: :center="ctrlloter"
3.到子组件中创建props
属性在属性中定义center
,可以为空,也可以定义它的变量类型,这里我定义为boolean
类型
就这样获取到父组件传过来的值
子组件传值给父组件的步骤:
1.当点击子组件内部的按钮的时候触发closeSon
方法,通过$emit
关键字把false
这个布尔类型传给父组件
2.子组件代码中this.$emit('formson',false);
formson 指的是父组件在调用子组件的html元素上,使用v-on:
进行对formson 方法进行监听
3.<sonbox @formson="fromsonFn" v-show="ctrlloter" :center="ctrlloter"></sonbox>
代码中 @formson
就是使用了v-on 的简写进行这个方法的监听而fromsonFn
是在父组件中定义的方法,用来接收子组件传过来的false
值
4.fromsonFn(val){ this.ctrlloter=val; }
这个方法在父组件中用来接收子组件传过来的值,赋值在ctrlloter
上,从而做到从父组件层级关闭子组件的显示