Vue入门【五】-- 组件通信
1.概述
组件是Vue中的一个重要概念,是一个可以重复使用的Vue是可以复用的Vue实例,它拥有独一无二的组件名称,它可以扩展HTML元素,以组件名称的方式作为自定义的HTML标签。因为组件是可复用的Vue实例,所以它们与new Vue()接收相同的选项,例如data,computed、watch、methods以及生命周期钩子等。仅有的例外是像el这样根实例特有的选项。
组件的特点:
- 组件可以进行任意次数的复用。
- 组件的data必须是一个函数,确保每个实例可以维护一份被返回对象的独立的拷贝,也就是任何一个组件的改变不会影响到其他组件。
2.组件的注册
任何组件在使用之前都得先进行组件的注册
组件注册分为:
全局注册和局部注册
2.1全局注册
语法:
Vue.component('组件名称', { })
第1个参数是标签名称,第2个参数是一个选项对象。全局组件注册后可以用在任何新创建的 Vue 根实例的模板中。
步骤:
- 定义组件配置对象
- 注册组件
- 使用组件
全局注册的特点:
一次定义,随时使用,一但声明完成,就可以在所有的组件中直接使用,无需引入和注册。
实例:
<body>
<div id="app">
<!-- 3.组件使用 -->
<my-a></my-a>
</div>
<script>
// 1.定义组件配置对象
let myA = {
template:`
<div>
{{msgA}}
</div>
`,
data(){
return{
msgA:'我是子组件'
}
},
methods:{
}
};
let myB = {
template:`
<div>B组件
-----------
<my-a></my-a>
</div>
`
}
// 2.注册组件
// 1.全局注册
Vue.component('my-a',myA)
Vue.component('my-b',myB)
// 3.使用组件
new Vue({
// 根组件
el:"#app",
data:{
msg:"父组件"
},
methods:{
}
})
</script>
</body>
2.2 局部注册
<body>
<div id="app">
<!-- 3.组件使用 -->
<my-a></my-a>
</div>
<script>
// 1.定义组件配置对象
let myA = {
template:`
<div>
{{msgA}}
</div>
`,
data(){
return{
msgA:'我是子组件'
}
},
methods:{
}
};
// 2.注册组件
new Vue({
// 2.局部注册 -- 只能在根组件内使用
// 因为是在根组件内注册的
components:{
'my-a':myA,
},
// 根组件
el:"#app",
data:{
msg:"父组件"
},
methods:{
}
})
</script>
</body>
注意:一般情况下,局部注册的组件只能在根组件内使用,因为是在根组件内注册的,如果需要在其他处使用的话需要再次注册,如:
我们再次定义了一个B组件,并希望在B内使用A组件,那么只要在B内注册一次A组件之后就可以在B组件内使用啦!(要记得在全局注册一次B哦!)
let myB = {
// 在B内注册之后就可以在B组件内使用啦
components:{
'my-a':myA
},
template:`
<div>B组件
-----------
<my-a></my-a>
</div>
}
3.组件通信
3.1 父组件向子组件
1.在父组件内导入注册子组件
2.在子组件内定义props,
// 接收父组传递的值
props:['age'],
3.使用子组件是在子组件的标签内写入要从父组件中传过来的值
<myon :msg="msg"></myon>
4.父组件中的data里返回要传递的msg
data:{
msg:'我是父组件'
}
整体过程是这样的:
3.2 子组件向父组件传值
1.在父组件内导入注册子组件
2.给子组件的template中的button按钮添加一个点击事件
template:`
<div>这里是子组件
<button @click='toSend'>传值给父</button>
</div>
`
3.在methods里定义这个方法,并触发一个中间事件my-event 去传递数据
methods: {
toSend(){
this.$emit('my-event',this.subMsg)
}
}
4. 在父组件中使用子组件时在子组件的标签内用前面定义的中间事件去绑定自己的响应事件handler
<div id="app">
<!-- 在父组件中使用子组件并在子组件的标签内定义自定义事件 -->
<myin @my-event="handler"></myin>
</div>
5. 在父组件的methods中添加handler事件接收数据,这里的参数a可以为任意字符
methods:{
handler(a){
console.log(a,'这是子组件的值');
}
}
整体过程如下:
3.3 使用eventbus进行任意组件传值
1.创建一个eventbus..js的新文件
import Vue from 'vue';
export default new Vue();
2.在需要通信的双方都导入1中的eventbus.js
import bus from '../eventbus';
3.发送事件 使用eventbus原型对象中的$emit发送数据
<button @click="handler">传值给Footer</button>
methods:{
handler(){
// 兄弟组件传值
// 1.兄弟组件使用$emit发射事件 携带参数、
bus.$emit('toFoot', this.Footer)
}
}
4.接收事件 使用eventbus原型对象中的$on接收数据
created(){
bus.$on('toFoot',(a)=>{
console.log(a,"这是Footer传过来的值");
})
}
3.4 provide 与 inject 进行组件通信
假设有一个组件A,A组件引入B组件(A为B的父组件) ,B组件引入C组件(B为C的父组件),即A为C的祖先组件,此时二者可以使用provide / inject进行通信。
1.注册C组件时记得在B组件中注册,不要在A中注册
2. 在祖先组件A使用provide方法提供传递的数据
// 祖先组件使用provide方法提供传递的数据
provide(){
return {"msg":this.msg}
}
3. 在孙组件C中使用inject注入需要传递的数据
inject:['msg'],
注意:
单向数据流(数据更改的方向)
父组件可以更改传递给子组件的数据 --父改子可以,但是子组件不可以更改父组件的数据 --子改父不行,即:
修改父组件的msg 子组件的msg跟着修改但是反过来不行