Vue 作为一个轻量级的前端框架,其核心就是组件化开发。Vue 就是由一个一个的组件构成的,组件化是它的精髓,也是最强大的功能之一。而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。
但在实际项目开发过程中,我们需要访问其他组件的数据,这样就就有了组件通信的问题。
对于组件之间的数据相互传递,一般有三种情况:父组件向子组件传值,子组件向父组件传值和兄弟组件之间的传值
一、父组件向子组件传值
父组件发送的形式是以属性的形式绑定值到子组件身上,然后子组件用属性props接收
注意在props中使用驼峰形式,模板中需要使用短横线的形式字,符串形式的模板中没有这个限制
示例:当点击按钮时,父组件中的num改变,子组件中的num也改变
<div id="app">
<p>{{num}}</p>
<input type="button" value="改变num" @click="updateNum">
<!--1、son 在 app中嵌套着 故son为子组件,在子组件中绑定动态属性 -->
<son v-bind:abc="num" ></son>
<!-- 2、需要动态的数据的时候 需要属性绑定的形式设置 此时 num 来自父组件data 中的数据,
传的值可以是数字(Number)、字符串(String)、对象(Object)、数组(Array)等等
-->
</div>
<script>
const app=new Vue({
el:'#app',
data:{
num:456
},
methods:{
updateNum(){
this.num=789
}
},
components:{
'son':{
// 3、 子组件用属性props接收父组件传递过来的数据
props:['abc'],
// props:['String','Number'] //例:可能传多个类型
// props:{
// abc:{
// type:String //例:字符串
// },
// def:{
// type:Number, //例:数字
// require:true,
// }
// },
data:function(){
return {}
},
template:`
<div>
<h3>son组件标题</h3>
<h4 v-text="abc"></h4>
</div>
`,
methods:{
}
}
},
})
</script>
二、子组件向父组件传值
子组件用$emit()
触发事件,$emit()
第一个参数为 自定义的事件名称 第二个参数为需要传递的数据,父组件用v-on 监听子组件的事件
示例:当点击子组件按钮时,子组件数据改变,父组件的数据也会改变
<div id="app">
<p>{{fmsg}}</p>
<input type="button" value="父组件按钮" v-on:click="update">
<son v-on:handle-info="getInfo($event,10)" :fmsg="fmsg"></son>
</div>
<script>
const app=new Vue({
el:'#app',
data:{
fmsg:'一条数据',
},
methods:{
update(){},
getInfo(val,num){
console.log(val,num)
this.fmsg=val
}
},
components:{
'son':{
props:['fmsg'],
data:function(){
return {
info:'一条数据'
}
},
template:`
<div>
<h3>son组件标题</h3>
<p>{{fmsg}}</p>
<input type="button" value="子组件按钮" @click="sendInfo">
</div>
`,
methods:{
sendInfo(){
//console.log(this.info)
//注册自定义事件
this.$emit('handle-info',this.info)
}
}
}
},
})
</script>
三、兄弟组件之间的传值
兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
提供事件中心 var hub = new Vue()
传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
接收数据方,通过mounted(){} 钩子中 触发hub.$on()
方法名
示例:当点击‘给亚索接大’时,亚索的‘地上五根线’将会变成‘势不可挡’
<div id="app">
<naruto></naruto>
<hasaki></hasaki>
</div>
<script>
//1、 提供事件中心
let tmpCom=new Vue()
const app=new Vue({
el:'#app',
data:{
},
methods:{
},
components:{
'naruto':{
template:`
<div>
<p>石头人</p>
<p>{{skill}}</p>
<input type="button" value="给亚索接大" @click="sendSkill">
</div>
`,
data:function(){
return {
skill:'势不可挡'
}
},
methods:{
sendSkill(){
//2、传递数据方,
//通过一个事件触发tmpCom.$emit(方法名,传递的数据)触发兄弟组件的事件
tmpCom.$emit('handle-n-skill',this.skill)
}
}
},
'hasaki':{
template:`
<div>
<p>亚索</p>
<p>{{jineng}}</p>
<input type="button" value="我是闪电!">
</div>
`,
data:function(){
return {
jineng:'地上五根线'
}
},
mounted(){
// 3、接收数据方,通过mounted(){} 钩子中 tmpCom.$on(方法名)
tmpCom.$on('handle-n-skill',val=>{
console.log(val)
console.log(this)
this.jineng=val
})
}
}
}
})
</script>