** 有时候需要实现一些功能时会用到组件之间的通信**
一、父传子–靠属性
比如需要做一个导航,在不同的页面需要显示不同的标题时,可以根据父组件传过来的属性来改变子组件的显示,下面的例子中,父组件是root(就是实例化的vue)
<body>
<div id="box">
<navbar myname = "position"></navbar>
<navbar myname = "list"></navbar>
<navbar myname = "shopcar"></navbar>
</div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
Vue.component('navbar',{
template:`
<div>
<button>首页</button>
navbar -- {{myname}}
<button>返回</button>
</div>`,
props:['myname'] //这里是接收父组件传来的属性,注意,这个是props不是prop啊!不然没法传过去!
})
new Vue({
el:'#box',
显示:
上面的例子属于属性的绑定,再使用,如果要在子组件中绑定父组件的值,需要动态绑定,用的是bind
<body>
<div id="box">
<navbar myname = "position"></navbar>
<navbar myname = "list"></navbar>
<navbar :myname = "parentname"></navbar>
</div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
Vue.component('navbar',{
template:`
<div>
<button>首页</button>
navbar -- {{myname}}
<button>返回</button>
</div>`,
props:['myname'] //这里是接收父组件传来的属性,注意,这个是props不是prop啊!不然没法传过去!
})
new Vue({
el:'#box',
data:{
parentname:"父组件的状态" //这里是父组件的状态,也是相当于是root,vue的实例
}
})
如果想要只显示一个导航栏,而不是三个都显示时,想要通过一个属性控制时,这时属性传递的是字符串,想要转成布尔值要用bind绑定
<body>
<div id="box">
<navbar myname = "position" :mystate = "false"></navbar>
<navbar myname = "list" :mystate = "true"></navbar>
<navbar :myname = "parentname" :mystate = "false"></navbar>
</div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
Vue.component('navbar',{
template:`
<div v-if = "mystate"> //这里用v-if来绑定这个状态
<button >首页</button>
navbar -- {{myname}}
<button>返回</button>
</div>`,
props:['myname','mystate'] //这里是接收父组件传来的属性,注意,这个是props不是prop啊!不然没法传过去!
})
new Vue({
el:'#box',
data:{
parentname:"父组件的状态"
}
})
进一步,如果想要进行【属性验证】,主要是将props写成是对象模式,比如上面的mystate应该是布尔类型的,不加动态绑定之前是字符串类型的,这样子就会报错,如:
加了冒号之后就可以了,动态绑定,相当于是变量那个样子
二、子传父–靠事件
子传父就好像孩子给父亲打钱一样,父亲需要给孩子银行卡号作为打钱的连接,整个逻辑是:触发子组件事件–> 分发的事件–>使得父组件的事件触发 --> 使得成功给父亲打钱
<body>
<div id="box" >
<!-- 父组件相当于这个box -->
父组件
<child @myevent = fatherCard($event)></child>
<!-- 在父组件中用了子组件,子组件传的值时加子组件那里的哦 ,这样是监听这个事件的意思,没有写$event时,是不用写括号的-->
<!--父组件的函数时绑定在这里的哦 -->
</div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
Vue.component("child",{
template:`
<div>
子组件
<button @click = paymoney()> 打钱 </button>
</div>`,
data(){
return{
childname:"子组件的状态"
}
},
methods:{
paymoney(){
this.$emit('myevent',2000) //找到这张银行卡号的意思,这里用的是$emit分发这个函数
}
}
})
new Vue ({
el:"#box",
methods:{
fatherCard(ev){
console.log('老子收到钱了!',ev) //这里的ev是固定的写法
}
}
})
传送子组件的状态时,可以这样子
子传父案例:通过子组件来获取父组件的数据(组件之间的数据作用域是不同的)
如果要实现点击按钮就控制列表的展示时,一般我们这样做:
<body>
<div id="box">
<!-- 这里是父组件 -->
<button @click = "isShow = !isShow" >确定</button>
<child v-show = "isShow"></child>
<!-- 这里的子组件看成是普通标签,之前的父组件给子组件传值靠的是属性 -->
</div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
Vue.component("child",{
template:`
<div style="background:yellow">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
`,
})
new Vue({
el:"#box",
data:{
isShow:false
}
})
但是,如果按钮是封装在一个组件当中的话,就需要用到父传子的功能了!
<body>
<div id="box">
<!-- 这里是父组件 -->
<!-- <button @click = "isShow = !isShow" >确定</button> -->
<navbar @myevent = "handleShow"> </navbar>
<!-- navbar子组件通过接收父组件的数据来控制子组件的展示 -->
<child v-show = "isShow"> </child>
</div>
</body>
<script src="./b_component/lib/vue.js"></script>
<script>
Vue.component("navbar", {
template:
`
<button @click = showList()> 确定 </button>
`,
methods:{
showList(){
this.$emit("myevent")
}
}
})
Vue.component("child", {
template: `
<div style="background:yellow">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
`,
})
new Vue({
el: "#box",
data: {
isShow: true
},
methods: {
handleShow() {
this.isShow = !this.isShow
}
}
})
</script>
总结:子组件访问父组件的数据时,相当于父组件个子组件通信,这时父组件的银行卡是绑在使用的子组件上的;
使用组件开发时,还是使用父子通信的方式来控制展示好些