组件之间的通信
问题:为什么组件里面的data选项是一个函数?
内部必须是一个函数返回对象的形式,这样的话就可以保证每一个组件里面用到的数据都是唯一的了。
一个组件的data必须是一个函数,因此可以让每个实例维护一份被返回对象的独立的拷贝
父子通信
父组件给子组件传递数据的时候,子组件需要利用props的属性来确定自己的预期数据
- 中间有 - 需要写出驼峰的形式来接收
- 如果子组件没有通过props属性接受传递过来的数据,则数据会以自定义属性的方式,放在子组件最外层的根元素上面**
<body>
<div id="app">
<father></father>
</div>
<!--父组件创建 -->
<template id="father">
<div>
<p>父组件</p>
<p>{{msg}}</p>
<!--1.父组件调用子组件的时候,给子组件以绑定属性的方式传递-->
<son :msg="msg"></son>
</div>
</template>
<!-- 子组件创建-->
<template id="son">
<div>
<p>子组件</p>
<!-- 子组件,如何获取父组件的msg数据 -->
<p>{{msg}}</p>
</div>
</template>
</body>
<script>
Vue.component("father", {
template: "#father",
data() {
return {
msg: "父组件的内容"
}
},
components:{
son:{
// 2.需要通过props属性来接收后使用
props: ["msg"],
template: "#son",
}
}
})
new Vue({
el: "#app",
})
</script>
子父通信
如下实例:父组件获取子组件的数据
通过属性绑定传递给子组件
<body>
<div id="app">
<father></father>
</div>
<!--父组件创建-->
<template id="father">
<div>
<p>父组件 {{msg}}</p>
<!--3.将更改自身数据的方法通过属性方式传递给子组件-->
<son :Schange="change"></son>
</div>
</template>
<!--子组件创建-->
<template id="son">
<div>
<p>子组件{{Smsg}}</p>
<p><button @click="say">点击</button></p>
</div>
</template>
</body>
<script>
Vue.component("father", {
template: "#father",
data() {
return {
msg: "" // 1.父组件声明一条数据用来接收数据
}
},
methods: {
change(val){ //2.父组件需要写一个更改自身数据的方法
this.msg=val //6.父组件接收到子组件传递过来的数据,赋值给父组件的msg
}
}
})
Vue.component("son", {
template: "#son",
props: ["Schange"], // 4.子组件需要通过props来接受父组件传递来的属性
data() {
return {
Smsg: "子组件的数据"
}
},
methods:{
say(){
this.Schange(this.Smsg) // 5.在子组件中声明一个方法,当点击按钮的时候,执行此方法,把子组件的msg作为实参传给Schange
}
}
})
new Vue({
el: "#app",
})
</script>
通过自定义事件
<body>
<div id="app">
<father></father>
</div>
<template id="father">
<div>
<p>父组件 {{msg}}</p>
<!--3.给子组件绑定一个自定义事件 @自定义事件名=父组件处理函数-->
<son @schange="change"></son>
</div>
</template>
<template id="son">
<div>
<p>子组件{{Smsg}}</p>
<p><button @click="say">点击</button></p>
</div>
</template>
</body>
<script>
Vue.component("father", {
template: "#father",
data() {
return {
msg: "" 1.父组件声明一条数据用来接收数据
}
},
methods: {
change(val){ //2.父组件需要写一个更改自身数据的方法
this.msg=val
}
}
})
Vue.component("son", {
template: "#son",
data() {
return {
Smsg: "子组件的数据"
}
},
methods:{
say(){
//4. 需要触发绑定在自身上面的change事件 <son @change="change"></son>
// 通过this.$emit方法就可以触发@后面的自定义事件,第二个参数就是可以传递参数过去
this.$emit("schange",this.Smsg)
}
}
})
new Vue({
el: "#app",
})
</script>
兄弟通信
组件间不仅可以用过$root/$parent/$children来获取对应关系的组件,
父组件还可以主动的通过ref为子组件做标记 也可以给dom做标记
也会形成ref链,也可以交互,
- viewmodel+ref链
<body>
<div id="app">
<sister></sister>
<brother ref="bro"></brother>
</div>
<template id="sister">
<div>
<p>姐姐</p>
<!--当点击hit时,让弟弟哭的行为显示出来-->
<p><button @click="hit">点击</button></p>
</div>
</template>
<template id="brother">
<div>
<p ref="style">弟弟</p>
<p v-show="isShow">{{action}}</p>
</div>
</template>
</body>
<script>
Vue.component("sister", {
template: "#sister",
data () {
return {
si:"姐姐"
}
},
methods: {
hit(){
// 关系链
// this.$parent.$children[1].isShow=true;
// ref链
this.$parent.$refs.bro.isShow=true;
this.$parent.$refs.bro.$refs.style.style.color= "red"
}
}
})
Vue.component("brother", {
template: "#brother",
data () {
return {
isShow:false,
bro:"弟弟",
action:"哭"
}
}
})
new Vue({
el: "#app",
})
</script>
event bus事件总线
angle.$on(事件名,执行的回调函数) angle.$emit(事件名,参数)
<body>
<div id="app">
<sister></sister>
<brother ref="bro"></brother>
</div>
<template id="sister">
<div>
<p>姐姐</p>
<p><button @click="hit">点击</button></p>
</div>
</template>
<template id="brother">
<div>
<p ref="style">弟弟</p>
<p v-show="isShow">{{action}}</p>
</div>
</template>
</body>
<script>
let cry = new Vue() //1.创建了一个公共的vue的实例对象
Vue.component("sister", {
template: "#sister",
data () {
return {
si:"姐姐"
}
},
methods: {
hit(){
//3.触发绑定的自定义事件
cry.$emit("crying")
}
}
})
Vue.component("brother", {
template: "#brother",
mounted () {
//2.需要绑定一个事件,等待触发
cry.$on("crying",this.crying)
},
methods:{
crying(){
this.isShow = true
}
},
data () {
return {
isShow:false,
bro:"弟弟",
action:"哭"
}
}
})
new Vue({
el: "#app",
})
</script>