Props $emit 方式
父子传参最常用的方式就是使用props,$emit
1. 父传子
子组件从父组件接受参数通过props,并且可以规定类型,默认值等
总结
1.父组件中 v-bind:parentToOne="parentMsg" ,
一般parentToOne 与 parentMsg 名称相同即可
即:v-bind:parentMsg="parentMsg" 下面props接收也改为parentMsg,这里为了阐明关系
2.子组件中Props接收 parentToOne
父组件
<template>
<div class="parent">
<SubOne :parentToOne="parentMsg"/>
</div>
</template>
<script>
import SubOne from './components/SubOne'
export default {
name:"parent",
data(){
return {
parentMsg:'parent',
}
},
components:{SubOne},
}
</script>
子组件
<template>
<h6>来自父组件的参数parentMsg:{{parentToOne}}</h6>
</template>
<script>
export default {
name: "SubOne",
props: {
//规定类型,默认值
parentToOne: {
type: String,
default: "xxx",
},
}
};
</script>
2. 父传子,且子组件修改props传递参数,通过sync 修饰符
总结
1.父组件中在给传递给子组件的参数添加sync修饰符
2.子组件中通过$emit('update: propName',value)
父组件
<h3>I am父组件</h3>
<SubTwo :parentMsg.sync="parentMsg"/>
子组件
<template>
<h6>
修改父数据:<input type="text" @input="msgChange">
</h6>
</template>
<script>
export default {
name: "SubTwo",
//接受参数
props: {
parentMsg: {
type: String,
default: "xxx",
},
},
methods:{
msgChange:function($event){
//在子组件方法里 通过$emit修改
this.$emit('update:parentMsg',$event.target.value)
}
},
};
</script>
3. 子传父
总结
1.父组件里 给子组件添加v-on 监听并绑定父组件方法接收参数
2.子组件里面 $emit通过subThree 触发reserveSubMsg
父组件
<template>
<div class="parent">
<h3>I am 父组件</h3>
<h6>接收subThree的参数 subMsg:{{subMsg}}</h6>
<SubThree v-on:subThree="reserveSubMsg"/>
</div>
</template>
<script>
import SubThree from './components/SubThree'
export default {
name:"parent",
data(){
return {
subMsg:''
}
},
components:{
SubThree
},
methods:{
reserveSubMsg(value){
this.subMsg = value
}
}
}
</script>
子组件
<template>
<div class="sub">
传递父数据:<input type="text" v-model="value" @input="msgChange">
</div>
</template>
<script>
export default {
name: "SubThree",
data() {
return {
value:''
};
},
methods: {
msgChange(){
this.$emit('subThree',this.value)
}
},
};
</script>
provide inject 方式
父子之间传递参数也是有缺点的,比如子组件嵌套很深的情况下,逐层传递会很麻烦,
provide-inject方式可以很方便的解决这个问题
总结
这种方式比较像发布订阅
1.在顶层组件中,通过provide 发布变量(与data同级)
2.顶层组件的子组件中都可以通过inject 接收到变量,可以直接通过this访问
顶级组件
provide() {
return {
topFloorMsg: "come from top",
};
},
子组件
//省略部分代码 完整代码见下
<h6>来自top组件的参数 topFloorMsg: {{topFloorMsg}}</h6>
inject:['topFloorMsg'],
bus 非组件之间传值
总结
思路:实例化一个vue实例,利用它身上的$emit $on
1. 生成实例,来做为中间传达的工具
2. 在任意组件 $emit 发布变量
3. 在任意组件 $on 订阅监听变量
//bus.js
import Vue from 'vue'
export default new Vue()
BusA
// 引入公共的bus,来做为中间传达的工具
import Bus from '@/bus.js'
//方法中触发
methods: {
usHandle(){
Bus.$emit('busMsg','come from bus')
}
},
BusB
<h6>来自Bud事件总线的 busMsg: {{ value }}</h6>
mounted(){
var vm = this;
// 用$on事件来接收参数
Bus.$on("busMsg", (data) => {
console.log(data);
vm.value = data;
});
},
完整代码
父组件
<template>
<div class="parent">
<div class="item">
<h3>父子传参 props $emit</h3>
<h6>父组件参数 parentMsg:{{ parentMsg }}</h6>
<h6>接收subThree的参数 subMsg:{{ subMsg }}</h6>
<SubOne :parentToOne="parentMsg" />
<SubTwo :parentMsg.sync="parentMsg" />
<SubThree v-on:subThree="reserveSubMsg" />
</div>
<div class="item">
<h3>Provide - Inject方式</h3>
<Son />
</div>
<div class="item">
<h3>Bus方式</h3>
<button @click="busHandle">传递参数</button>
<BusA/>
</div>
</div>
</template>
<script>
import SubOne from "./components/SubOne";
import SubTwo from "./components/SubTwo";
import SubThree from "./components/SubThree";
import Son from "./components/Son";
// 引入公共的bug,来做为中间传达的工具
import Bus from '@/bus.js'
import BusA from "./components/BusA";
export default {
name: "parent",
data() {
return {
parentMsg: "parent",
subMsg: "",
};
},
provide() {
return {
topFloorMsg: "come from top",
};
},
components: {
SubOne,
SubTwo,
SubThree,
Son,BusA
},
methods: {
reserveSubMsg(value) {
this.subMsg = value;
},
busHandle(){
Bus.$emit('busMsg','come from bus')
}
},
};
</script>
<style lang="scss" scoped>
.parent {
padding: 20px;
background: #ffffff;
border: 1px dashed pink;
display: flex;
justify-content: space-around;
.item{
width: 33%;
}
}
</style>
SubOne
<template>
<div class="sub">
<h3>I am subOne 子组件 我专门接受父组件参数</h3>
<h6>来自父组件的参数parentMsg:{{parentToOne}}</h6>
</div>
</template>
<script>
export default {
name: "SubOne",
props: {
parentToOne: {
type: String,
default: "xxx",
},
}
};
</script>
<style lang="scss" scoped>
.sub{
border: 1px dashed #333332;
background: lightblue;
}
</style>
SubTwo
<template>
<div class="sub">
<h3>I am subTwo 子组件 我接受并修改父组件参数</h3>
<h6>来自父组件的参数parentMsg:{{parentMsg}}</h6>
<h6>
修改父数据:<input type="text" @input="msgChange">
</h6>
</div>
</template>
<script>
export default {
name: "SubTwo",
props: {
parentMsg: {
type: String,
default: "xxx",
},
},
methods:{
msgChange:function($event){
console.log($event.target.value);
this.$emit('update:parentMsg',$event.target.value)
}
},
};
</script>
<style lang="scss" scoped>
.sub{
margin-top: 20px;
border: 1px dashed #333332;
background: lightblue;
}
</style>
SubThree
<template>
<div class="sub">
<h3>
I am subThree 子组件 我给父组件传递参数
</h3>
传递父数据:<input type="text" v-model="value" @input="msgChange">
</div>
</template>
<script>
export default {
name: "SubThree",
data() {
return {
value:''
};
},
components: {},
methods: {
msgChange($event){
console.log($event.target.value);
this.$emit('subThree',this.value)
}
},
};
</script>
<style lang="scss" scoped>
.sub{
border: 1px dashed #333332;
background: lightblue;
}
</style>
son
<template>
<div class="sub">
<h3>
I am Son 子组件
</h3>
<h6>来自top组件的参数 topFloorMsg: {{topFloorMsg}}</h6>
<!-- <Grandson/> -->
</div>
</template>
<script>
// import Grandson from './Grandson'
export default {
name: "Son",
inject:['topFloorMsg'],
components:{
// Grandson
}
};
</script>
<style lang="scss" scoped>
.sub{
border: 1px dashed #333332;
background: lightblue;
}
</style>
BusA.vue
<template>
<div class="sub">
<h3>
I am BusA 子组件
</h3>
<h6>来自Bud事件总线的 busMsg: {{ value }}</h6>
</div>
</template>
<script>
import Bus from "@/bus.js";
export default {
name: "BusA",
data(){
return{
value:''
}
},
mounted(){
var vm = this;
// 用$on事件来接收参数
Bus.$on("busMsg", (data) => {
console.log(data);
vm.value = data;
});
},
};
</script>
<style lang="scss" scoped>
.sub {
border: 1px dashed #333332;
background: lightblue;
}
</style>