在子组件中声明props,属性可以是数组(元素必须是字符串)、也可以是对象,声明的每一个属性值都可以作为子组件的属性使用
props也是双向绑定的
注意:不建议子组件直接修改props里面的值,由父组件传值,子组件只使用,如果需要修改,在data中重新声明一个变量来接收prop
父组件Father.vue
<template>
<div>
<!-- 父组件向子组件传参 -->
<Child :msg="hello"/>
</div>
</template>
<script>
import Child from './Child.vue';
export default {
name: "Father",
components: {
Child
},
data() {
return {
hello: 'Hello World',
};
},
}
</script>
子组件Child.vue
<template>
<div>
{{msg}}
</div>
</template>
<script>
export default {
name: "Child",
// 子组件进行接收
props: ['msg']
/**
props还可以是一个对象,可以对传入子组件的数据进行验证,例如字符串和数组
props:{
类型验证
parentcolor:String,
msg:Array,
类型、默认值、必填项
book:{
type:Array,
default:["200","201"],
required:true
}
}
*/
}
</script>
<template id="temp1">
<h1>
<!-- 通过this.$parent.属性名访问父组件的属性值、方法 -->
<font :color="this.$parent.parentColor">test</font>
</h1>
</template>
注意:在vue中的ref
属性,相当于原生html的id,给子组件设置一个id,然后this.$refs.id
可以进行调用,返回该组件的实例对象;也可以用在原生html标签上,返回该标签的Dom对象
子组件Child.vue
<template>
</template>
<script>
export default {
name: "Child",
data() {
return {
msg: 'Hello World',
};
},
methods: {
say(){
alert(this.msg);
}
}
}
</script>
父组件Father.vue
<template>
<div>
<!-- 在子组件上绑定ref唯一标识 -->
<Child ref="ch1"/>
<button @click="runSay">click</button>
</div>
</template>
<script>
import Child from './Child.vue';
export default {
name: "Father",
components: {
Child
},
methods: {
runSay(){
// 利用 this.$ref 调用子组件方法
this.$refs.ch1.say();
// 利用 this.$ref 访问子组件data
console.log(this.$refs.ch1.msg);
}
}
}
</script>
父组件给子组件绑定一个事件,子组件可以通过触发这个事件来调用父组件的回调,达到通讯的作用
this.$emit("自身上的事件",方法形参)
父组件Father.vue
<template>
<div>
<!-- 在子组件上绑定自定义事件 -->
<Child ref="ch" @runShowMsg="showMsg"/>
<!-- !!!如果需要在子组件上绑定原生dom事件,需要使用native -->
<Child ref="ch" @click.native="showMsg"/>
</div>
</template>
<script>
import Child from './Child.vue';
export default {
name: "Father",
components: {
Child
},
methods: {
showMsg(msg){
alert(msg);
}
},
mounted(){
//!!!也可以通过获取子组件的组件实例对象,直接在实例对象上绑定事件
//this.$refs.ch.$on("runShowMsg",this.showMsg); //绑定自定义事件
//this.$refs.ch.$once(); //绑定只可触发一次的自定义事件
}
}
</script>
子组件Child.vue
<template>
<button @click="cl">click</button>
</template>
<script>
export default {
name: "Child",
methods: {
cl(){
// 触发自身的事件
this.$emit('runShowMsg', "Hello World");
//也可以使用组件实例对象的$off函数解绑事件
//this.$off('runShowMsg') //解绑一个事件
//this.$off(['event1','event2']) //解绑多个事件
//this.$off() //解绑s
}
}
}
</script>
可以实现任意组件间进行通讯
main.js
中安装全局事件总线
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 原理:在Vue原型对象上绑定一个空的组件,组件实例对象都支持$on、$once、$off等方法操作自定义事件
// const Bus = Vue.extend({})
// Vue.prototype.$bus = new Bus()
new Vue({
render: h => h(App),
beforeCreate(){
//进阶写法:在组件还未创建前,将当前Vue实例对象,作为全局事件总线使用
Vue.prototype.$bus = this;
}
}).$mount("#app")
接收方组件
注意:在组件接收方组件销毁之前,最好使用钩子beforeDestroy()删除声明的自定义事件,以免事件重复命名
<template>
</template>
<script>
export default {
name: "Comp2",
methods: {
getMsg(msg){
alert(msg)
}
},
mounted () {
//接收方,在全局事件总线上绑定一个事件和回调
this.$bus.$on("msgToComp2",this.getMsg)
},
beforeDestroy () {
//组件销毁前,删除绑定在全局事件总线上的事件
this.$bus.$off("msgToComp2");
}
}
</script>
发送方组件
<template>
<button @click="sendMsg">click</button>
</template>
<script>
export default {
name: "Comp1",
methods: {
sendMsg(){
// 发送方,触发全局事件总线的事件,并传参
this.$bus.$emit("msgToComp2","Hello World");
}
}
}
</script>
使用这个功能,需要引入第三方库,例如pubsub-js
,该库不依赖与vue,可以在其他js中使用
cnpm i pubsub-js
订阅方
<template>
<button @click="sendMsg">click</button>
</template>
<script>
import pubsub from 'pubsub-js';
export default {
name: "Comp1",
methods: {
sendMsg(){
// 发送方,调用pubsub.publish(消息名,接收回调函数的形参)发送消息
pubsub.publish("msg1","Hello World")
}
}
}
</script>
发布方
<template>
</template>
<script>
import pubsub from 'pubsub-js';
export default {
name: "Comp2",
methods: {
//注意:回调函数有两个参数,第一个是消息名,第二个才是消息
getMsg(msgName,msg){
alert(msg)
}
},
mounted () {
//接收方,使用pubsub.subscribe(消息名,回调函数)订阅,并且返回订阅id
this.pubId = pubsub.subscribe("msg1",this.getMsg);
},
beforeDestroy () {
//组件销毁前,使用订阅id取消订阅
pubsub.unsubscribe(this.pubId);
}
}
</script>