(九)父子组件的相互传值及非父子组件传值
父子组件的相互传值及非父子组件传值
1.首先明确一点 什么是父子组件,其实很简单哈,就是再明确一下,存在引用关系,一个组件引用了一个组件那么他们就是父子组件 对不,我包含着你 我引用了了你 我就是你爸 对吧 哈哈哈
这话就是 父子组件都是是相对而言的,有了子组件,他才是父组件。没有子组件,那都叫组件。
父子组件的关系可以总结为 通过 prop 向下传递,通过事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息
举例子传值 父到子
//父组件
<template>
<div class="map">
<p>这是父组件</p>
<zi :dataname="dataname"></zi>
</div>
</template>
<script>
import zi from "./zi";
export default {
name: "fu",
components: {
zi
},
data() {
return {
dataname: "我是要传递的值"
};
}
};
</script>
<style>
</style>
<template>
<div class="map">
<h2>这是子组件</h2>
<h2>{{dataname}}</h2>
</div>
</template>
<script>
export default {
name: "zi",
props: ["dataname"]
};
</script>
<style>
</style>
注意:这个地方有一个误区,是我理解的有偏差,就是你在写的时候,父组件打开之后流程是把值传入到子组件里面然后显示子组件,并不是直接将数据传递到了子组件里面, 直接打开子组件是没有信息显示的
举例子传值 子到父
同过事件上传数据
<!-- 父组件 -->
<template>
<div class="test">
<zi @childFn="parentFn"></zi>
<br />
子组件传来的值 : {{message}}
</div>
</template>
<script>
import zi from "./zi";
export default {
components: {
zi
},
data() {
return {
message: ""
};
},
methods: {
parentFn(shuju) {
this.message = shuju;
}
}
};
</script>
<!-- 子组件 -->
<template>
<div class="testCom">
<input type="text" v-model="message" />
<button @click="click">Send</button>
</div>
</template>
<script>
export default {
// ...
data() {
return {
// 默认
message: "我是来自子组件的消息"
};
},
methods: {
click() {
this.$emit("childFn", this.message);
}
}
};
</script>
有一种在父组件里面去要值的感觉哈
非父子组件传值
可以使用一个空vue实例作为事件中央线!
也就是说 非父子组件之间的通信,必须要有公共的实例(可以是空的),才能使用 $emit 获取 $on 的数据参数,实现组件通信
1.新建公共实例文件bus.js,作为公共数控中央总线(我看网上都用这个名字)
import Vue from "vue";
export default new Vue();
第一个组件
import Bus from '../bus.js';
export default {
name: 'first',
data () {
return {
value: '我是要发送的信息!'
}
},
methods:{
add(){// 定义add方法,并将msg通过txt传给second组件
Bus.$emit('message',this.value);
}
}
}
第二个组件
import Bus from '../bus.js';
export default {
name: 'second',
data () {
return {
}
},
//mounted在模板渲染成html后调用,通常是初始化页面完成后
mounted:function(){
Bus.$on('message',function(val){//监听first组件的txt事件
console.log(val);
});
}
}
你会看到传值也是用的$emit 看到网上有个人总结的蛮好的
兄弟组件之间与父子组件之间的数据交互,两者相比较,兄弟组件之间的通信其实和子组件向父组件传值有些类似,其实他们的通信原理都是相同的,
例如子向父传值也是$ emit和$on的形式,只是没有eventBus,但若我们仔细想想,此时父组件其实就充当了bus这个事件总线的角色。
这种用一个Vue实例来作为中央事件总线来管理组件通信的方法只适用于通信需求简单一点的项目,对于更复杂的情况,Vue也有提供更复杂的状态管理模式Vuex来进行处理
上述只是完成相应的操作啥的
有很多可以拓展的地方及相应的写法
Such as(例如)
props:{
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
//等等还有很多 我用过第一个跟第三个
}
拓展
在进行父子组件传值的时候 可能会遇到 在生命周期里面进行数据请求 ,然后传给子组件,发现数据传不过去,因为数据异步请求的操作得不到值,
解决办法就是在,在子组件上面写一个 v-if 判断条件是请求的数据不能为空的 ,再进行渲染数据。