Vue里组件的通信
通信:传参、控制(A操控B做一个事件)、数据共享
!!!组件中的数据只能由组件其自身修改,所有方法最终操作数据的都是其组件自身!!!
- 兄弟之间通信的话:viewmodel链 ref链 eventbus事件总线
- 父亲—>子组件 props获取父亲传递来的数据 数据只能由自身更改!
- 子组件–>父组件 1)父组件将更改自身数据的方法传递给子组件 2)事件触发与事件绑定的能力
模式:父子组件间、非父子组件
1、父组件将其自身操作数据的方法通过v-bind传递给子组件,子组件调用这个方法时,就可以给父组件传递数据
- 这里父组件通过 :tell-dad=“change” 将其自身的change方法传递给子组件,子组件通过props来接收父组件传递过来的方法:props:[“tellDad”] (当遇到-减号的时候用驼峰写法)
- 当子组件调用tellDad方法时,就会调用父组件的change方法,并将子组件自身的msg传过去
<template id="father">
<div class="father">
<p>这是父组件</p>
<p>这是儿子跟他说的话 {{parentMsg}} </p>
<hr>
<son :tell-dad="change"></son>
</div>
</template>
<template id="son">
<div class="son">
<p>这是子组件===》{{msg}}</p>
<p><button @click="tellDad(msg)">告诉爸爸</button></p>
</div>
</template>
<script>
// 父组件可以将自己方法传递给子组件来调用,
//实现子组件更改父组件的数据
Vue.component("father",{
template:"#father",
data(){
return {
parentMsg:""
}
},
methods:{
change(msg){
this.parentMsg = msg;
}
}
})
Vue.component("son",{
template:"#son",
props:["tellDad"],
data(){
return {
msg:"今晚不学习了。。"
}
}
})
new Vue({
el:"#app"
})
</script>
2、每一个组件或者实例都会有自定义事件,和触发事件的能力,父组件给子组件绑定一个自定义事件,这个事件的处理程序却是父组件的一个方法,当子组件触发这个事件的时候,相当于父组件的方法被执行
- 这里父组件通过@tell-dad=“change”给子组件绑定父组件自身的change方法。
- vue中通过this.$emit触发自定义事件 (事件名,参数)
- 点击子组件的按钮时,触发tell方法,而tell方法中通过$emit触发了父组件绑定在在子组件上的tell-dad方法,并且将msg数据当参数传递过去。调用了父节点的change方法。
<body>
<div id="app">
<father></father>
</div>
<template id="father">
<div class="father">
<p>这是父组件 ==> {{parentMsg}}</p>
<hr>
<son @tell-dad="change"></son>
</div>
</template>
<template id="son">
<div class="son">
<p>这是子组件</p>
<p><button @click="tell">btn</button></p>
<p>{{msg}}</p>
</div>
</template>
</body>
<script src="./base/vue.js"></script>
<script>
Vue.component("father",{
template:"#father",
data(){
return {
parentMsg:""
}
},
methods:{
change(msg){
this.parentMsg = msg
}
}
})
Vue.component("son",{
template:"#son",
methods:{
tell(){
//触发绑定在自身的事件 tell-dad
//vue中通过this.$emit触发自定义事件 (事件名,参数)
this.$emit("tell-dad",this.msg)
// this.tellDad(this.msg);
}
},
data(){
return {
msg:"今天天气不错!"
}
}
})
new Vue({
el: "#app"
})
</script>
案例
国王组件中有数据国库,只能国王操作国库的数据,国王下的子民需要每次都上供自身一半的工资到国库中,但是子民不能直接操作国库的数据。
- 国王将自身的addMoney方法 :_give=“addMoney” 传递给子民。子民通过props接收该方法 props:["_give"] 子民通过调用_give来上供。
<body>
<div id="app">
<king></king>
</div>
<template id="king">
<div>
<p>我是国王~~</p>
<p>国库:{{gk}}</p>
<p>下面是我的子民</p>
<hr>
<pi :_give="addMoney"></pi>
</div>
</template>
<template id="pi">
<div>
<p>我是伟大国王的子民</p>
<input type="number" v-model="money">
<p><button @click="jg">进贡</button></p>
</div>
</template>
<script src="/base/vue.js"></script>
<script>
Vue.component("king",{
template:"#king",
data(){
return {
gk:0
}
},
methods:{
addMoney(money){
this.gk += money;//King自己更改gk的数据
}
}
})
Vue.component("pi",{
template:"#pi",
data(){
return {
money:100
}
},
methods:{
jg(){
this.money /= 2;
this._give(this.money)
}
},
props:["_give"]
})
new Vue({
el:"#app"
})
</script>
</body>
3、 组件之间不仅可以通过$root $parent $children 来获取对应关系的组件,父组件还可以主动的通过ref为子组件做标记,也可以给dom做标记,也会形成ref链,可也以交互
【注】多个子组件标记的是同一个键名,获取到的应该是一个数组
父组件给子组件做$ref标记
- 父组件aaa 给子组件bbb标记ref=“b”
<template id="aaa">
<div>
<button ref='btn' @click="get">get</button>
<hr>
<bbb ref="b"></bbb>
</div>
</template>
<template id="bbb">
<div>
<input type="text" v-model="msg">
</div>
</template>
- 在父组件的get中通过$refs.b找到子组件b标记,修改b中的msg数据
<script>
Vue.component("aaa",{
template:"#aaa",
methods:{
get(){
// this.$children[0].msg = "bbbb"; //关系链 viewmodel链实现的
this.$refs.b.msg = "bbbbbb" //ref链实现的
}
}
})
Vue.component("bbb",{
template:"#bbb",
data(){
return {
msg:""
}
}
})
new Vue({
el:"#app"
})
</script>
4、 兄弟组件之间的通讯也是通过viewmodel关系链 和 $ref关系链来实现
通过big-borther的hitLittle方法,修改little-borther的crying的数据
<body>
<div id="app">
<big-borther></big-borther>
<little-borther ref="little"></little-borther>
</div>
<template id="big-borther">
<div>
<p>我是大哥哥</p>
<button @click="hitLittel">打弟弟</button>
<hr>
</div>
</template>
<template id="little-borther">
<div>
<p>我是小弟弟</p>
<p v-if="crying">我枯了…………</p>
</div>
</template>
<script src="/base/vue.js"></script>
<script>
Vue.component("big-borther",{
template:"#big-borther",
methods:{
hitLittel(){
// this.$refs.little.crying = true//通过refs标记来通讯
this.$parent.$children[1].crying=true//通过parent children关系链
}
}
})
Vue.component("little-borther",{
template:"#little-borther",
data(){
return {
crying:false
}
}
})
new Vue({
el:"#app"
})
</script>
</body>
5、 eventbus事件总线
- 1.创建一个空的Vue实例 eventbus 事件总线 绑定与触发事件的过程
创建vue对象 var angle = new Vue() - 2.B组件绑定一个自定义事件,第二个参数为需要执行的处理函数
angel.$on(“事件名”,this.cry) - 3.A组件要执行B组件的事件名就可以让B组件自己去执行cry的方法
angle.$emit(“事件名”)
<body>
<div id="app">
<big-borther></big-borther>
<little-borther></little-borther>
</div>
<template id="big-borther">
<div>
<p>我是大哥哥</p>
<button @click="hitLittel">打弟弟</button>
<hr>
</div>
</template>
<template id="little-borther">
<div>
<p>我是弟弟</p>
<p v-if="crying">我枯了…………</p>
</div>
</template>
<script src="/base/vue.js"></script>
<script>
//1、创建一个公共实例
var angel = new Vue();
Vue.component("big-borther",{
template:"#big-borther",
methods:{
//3、通过$emit触发$on绑定的事件函数little
hitLittel(){
angel.$emit("little")
}
}
})
Vue.component("little-borther",{
template:"#little-borther",
data(){
return {
crying:false
}
},
methods:{
cry(){
this.crying = true
}
},
mounted(){
//2、给angel通过$on绑定cry事件,叫做 little
angel.$on("little",this.cry)
}
})
new Vue({
el:"#app"
})
</script>
</body>
《个人笔记》