父组件向子组件传值
1、在父组件中引入
import blogpost from '@/components/blog-post.vue'
2、在components
里写上组件
import blogpost from '@/components/blog-post.vue'
export default {
data(){
return{
}
},
methods:{
},
components:{
blogpost: blogpost
}
}
3、在父组件用到子组件的地方加上属性
<blogpost title="这是title"></blogpost>
这个是静态prop
,也可以使用动态prop
例如,把title
绑定给一个data
<template>
<div>
homepage
<blogpost :title="title"></blogpost>
</div>
</template>
<script>
import blogpost from '@/components/blog-post.vue'
export default {
data(){
return{
title:"data里的title"
}
},
methods:{
},
components:{
blogpost: blogpost
}
}
</script>
4、在子组件里用props
来接收父组件传递的数据
export default {
data(){
return{
}
},
methods: {
},
props:['title']
}
5、在子组件里使用
<template>
<div>
这是blog-post组件
{{ title }}
</div>
</template>
Prop 是单向绑定的:当父组件的属性变化时会传导给子组件,但是不会反过来。
所有的 prop 都使得其父子 prop 之间形成了一个 单向下行绑定:
父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
另外,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。
这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
这里有两种常见的试图变更一个 prop 的情形:
这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。
在这种情况下,最好定义一个本地的 data property 并将这个 prop 作为其初始值:
props: ['initialCounter'],
data() {
return {
counter: this.initialCounter
}
}
这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
normalizedSize() {
return this.size.trim().toLowerCase()
}
}
监听子组件事件
1、子组件使用$emit(eventName)
触发事件
<button @click="$emit('changeTitle')">通过$emit()触发事件</button>
2、父组件使用$on(eventName)
监听子组件通过$emit
触发的事件
<blogpost :title="title" @changeTitle="change"></blogpost>
3、实现父组件里的事件change
<template>
<div>
homepage
<blogpost :title="title" @changeTitle="change"></blogpost>
</div>
</template>
<script>
import blogpost from '@/components/blog-post.vue'
export default {
data(){
return{
title:"data里的title"
}
},
methods:{
change(){
this.title = "title改变了"
}
},
components:{
blogpost: blogpost
}
}
</script>
<style>
</style>
也可以用事件抛出一个值
1、子组件使用$emit(eventName)
触发事件,并给emit
函数传递第二个参数
<button @click="$emit('changeTitle','这个是子组件抛出的值,赋值给父组件的title')">通过$emit()触发事件并抛出一个值</button>
2、父组件使用$on(eventName)
监听子组件通过$emit
触发的事件
<blogpost :title="title" @changeTitle="change($event)"></blogpost>
3、实现父组件里的事件change
<template>
<div>
homepage
<blogpost :title="title" @changeTitle="change($event)"></blogpost>
</div>
</template>
<script>
import blogpost from '@/components/blog-post.vue'
export default {
data(){
return{
title:"data里的title"
}
},
methods:{
change(event){
console.log(event);//这个是子组件抛出的值,赋值给父组件的title
this.title = event
}
},
components:{
blogpost: blogpost
}
}
</script>
这样父组件就拿到了子组件中的值
子组件之间通过父组件通信
可以看出子组件之间通过父组件通信就是其中子组件向父组件抛出一个值+父组件向另一个子组件传值,重点在是在父组件中把子组件抛出的值绑定给另一个子组件的属性
BrotherCard.vue
<!-- BrotherCard.vue -->
<template>
<div class="message">
<div class="message-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="message-body">
<p class="message-text">我是Brother组件</p>
<button @click="messageSister" class="btn">给妹妹发消息</button>
<div v-if="message" v-html="message"></div>
</div>
</div>
</template>
<script>
import emitter from '@/utils/bus'
export default {
name: "BrotherCard",
data: () => ({
theCardTitle: "子组件1",
message:""
}),
methods: {
messageSister() {
emitter.emit("brotherSaid", "messageSister,妈妈说,该做作业了!(^_^)!!!");
},
},
created() {
emitter.on("sisterSaid", e => { console.log(e); this.message = e});
}
};
</script>
ParentVard.vue
<template>
<div class="card">
<div class="card-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="card-body">
<brother-card class="subcard"></brother-card>
<sister-card class="subcard"></sister-card>
</div>
</div>
</template>
<script>
import BrotherCard from "@/views/ComponentsCommunicationMitt/BortherCard"
import SisterCard from "@/views/ComponentsCommunicationMitt/SisterCard"
export default {
name: "ParentCard",
data: () => ({
theCardTitle: "父组件",
}),
components: {
BrotherCard,
SisterCard,
},
};
</script>
<style>
.card{
border:solid;
padding:50px;
height:auto;
}
.subcard{
border:solid;
padding:0px;
}
</style>
SisterCard.vue
<!-- SisterCard.vue -->
<template>
<div class="message">
<div class="message-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="message-body">
<p class="message-text">我是Sister组件</p>
<button @click="messageBrother" class="btn">给哥哥发消息</button>
<div v-if="messageDaughter" class="alert" v-html="messageDaughter"></div>
<div class="alert" v-if="message" v-html="message"></div>
</div>
</div>
</template>
<script>
import emitter from '@/utils/bus'
export default {
name: "SisterCard",
data: () => ({
theCardTitle: "子组件2",
message:""
}),
methods: {
messageBrother() {
emitter.emit("sisterSaid", "messageBrother,妈妈说,该做作业了!(^_^)!!!");
},
},
created() {
emitter.on("brotherSaid", e => { console.log(e); this.message = e });
}
};
</script>
兄弟组件之间通过mitt库通信
1、安装
npm i mitt --save
2、新建文件bus.js
import mitt from 'mitt'
const emitter = mitt()
export default emitter
3、使用
BrotherCard.vue
<!-- BrotherCard.vue -->
<template>
<div class="message">
<div class="message-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="message-body">
<p class="message-text">我是Brother组件</p>
<button @click="messageSister" class="btn">给妹妹发消息</button>
<div v-if="message" v-html="message"></div>
</div>
</div>
</template>
<script>
import emitter from '@/utils/bus'
export default {
name: "BrotherCard",
data: () => ({
theCardTitle: "子组件1",
message:""
}),
methods: {
messageSister() {
emitter.emit("brotherSaid", "messageSister,妈妈说,该做作业了!(^_^)!!!");
},
},
created() {
emitter.on("sisterSaid", e => { console.log(e); this.message = e});
}
};
</script>
SisterCard.vue
<!-- SisterCard.vue -->
<template>
<div class="message">
<div class="message-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="message-body">
<p class="message-text">我是Sister组件</p>
<button @click="messageBrother" class="btn">给哥哥发消息</button>
<div v-if="messageDaughter" class="alert" v-html="messageDaughter"></div>
<div class="alert" v-if="message" v-html="message"></div>
</div>
</div>
</template>
<script>
import emitter from '@/utils/bus'
export default {
name: "SisterCard",
data: () => ({
theCardTitle: "子组件2",
message:""
}),
methods: {
messageBrother() {
emitter.emit("sisterSaid", "messageBrother,妈妈说,该做作业了!(^_^)!!!");
},
},
created() {
emitter.on("brotherSaid", e => { console.log(e); this.message = e });
}
};
</script>
ParentCard.vue
<template>
<div class="card">
<div class="card-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="card-body">
<brother-card class="subcard"></brother-card>
<sister-card class="subcard"></sister-card>
</div>
</div>
</template>
<script>
import BrotherCard from "@/views/ComponentsCommunicationMitt/BortherCard";
import SisterCard from "@/views/ComponentsCommunicationMitt/SisterCard";
export default {
name: "ParentCard",
data: () => ({
theCardTitle: "父组件",
}),
components: {
BrotherCard,
SisterCard,
},
};
</script>
<style>
.card{
border:solid;
padding:50px;
height:auto;
}
.subcard{
border:solid;
padding:0px;
}
</style>
参考1:https://www.cnblogs.com/zhilu/p/13851827.html
参考2:https://blog.csdn.net/jiangsheer/article/details/121394348