一:父组件传子组件,子组件接收
-
父组件传递:
如果子组件做为标签在父组件进行使用的时候,需要在父组件内部的子组件标签上面添加自定义属性,值为需要传递的数据
<template>
<div id="app">
<h1>appVue父组件</h1>
<Child1 :dataVal="msg"/> <!-- 在标签 绑定dataVal自定义属性 -->
</div>
</template>
<script>
import Child1 from './components/child1'
export default {
components:{
Child1,
},
data(){
return {
"msg" : '父组件传递的数据'
}
}
}
</script> -
子组件接收:( 在子组件内部通过props进行接收 -> props属性用来接收外部数据 )
-
第一种接收方法:
<template>
<div>
<h2>child1组件接收父组件数据:{{dataVal}}</h2>
</div>
</template>
<script>
export default {
props : ["dataVal"] //通过数组进行接收
}
</script> -
第二种接收方法:
<template>
<div>
<h2>child1组件接收父组件数据:{{dataVal}}</h2>
</div>
</template>
<script>
export default {
props : {
dataVal : { //通过对象进行接收
type : String, //限制数据类型(注:如果传递的数据非当前规定的数据类型,在开发环境下控制台会有警告,但是项目仍能跑)
default : '默认值', //默认数据:如果父组件没有传递数据,则接收当前默认数据
required : true //限制必须有数据的传递,如果没有数据传递则报出警告,
}
}
}
//注: default属性和required属性 两个选取一个存在即可。
</script>
-
二:子组件传递,父组件接收
-
父组件接收:
当子组件在父组件里面当作标签进行应用的时候,给当前子组件绑定一个自定义事件,值为需要接收值得函数,这个函数在应用得时候不需要加()
<template>
<div id="app">
<h1>appVue父组件</h1>
<p>{{msg}}</p>
<Child2 @handleGet="getVal"/> <!-- 给当前标签添加自定义事件,值为需要接收值得函数 -->
</div>
</template>
<script>
import Child2 from './components/child2'
export default {
data(){
return {
msg : ""
}
},
components:{
Child2,
},
methods : {
getVal(val){
this.msg = val;
}
}
}
</script> -
子组件传递:
在子组件里面需要用 this.$emit('自定义事件的名称',需要传递的参数) 进行数据传递
<template>
<div>
<h3>child2组件</h3>
<button @click="sendData">向父组件传递数据</button>
</div>
</template>
<script>
export default {
methods: {
sendData(){
this.$emit('handleGet','child2传递的数据'); //this.$emit第一个参数为 父组件标签内部自定义得事件得名称
}
},
}
</script>
三:非父子组件传值
1:第一种方法:
在Vue的原型上挂一个Vue的实例,需要传递数据的一方调用 $emit 需要接收数据的一方调用$on
弊端:因为需要在原型上挂一个Vue实例,但是我们用到的只是$on $emit方法,所以会产生性能消耗。
-
在Vue的原型上挂一个Vue的实例,每个组件都能访问这个实例上面的方法 ( main.js中操作 )
Vue.prototype.$observer = new Vue();
-
传递
<template>
<div class="box">
<button @click="sendDate">向其他组件传递数据</button>
</div>
</template>
<script>
export default {
methods: {
sendDate(){
this.$observer.$emit('getDate','child3组件传递的数据')
}
},
}
</script> -
接收
<template>
<div class="box">
<h2>接受到child3组件传递的数据为:{{val}}</h2>
</div>
</template>
<script>
export default {
data(){
return{
val : ''
}
},
created() { //尽量要在声明周期中使用 $on
this.$observer.$on('getDate',(val) => {
this.val = val;
})
},
}
</script>
2:第二种方法
观察者模式:封装 $on $emit $off 放在src文件下面observer.js 然后放在Vue的原型上面(在 main.js操作即可)
const eventList = {};
const $on = function(eventName,callback){
if(!eventList[eventName]){
eventList[eventName] = [];
}
eventList[eventName].push(callback);
}
const $emit = function(eventName,param){
if(eventList[eventName]){
let fnArr = eventList[eventName];
fnArr.forEach((callback) => {
callback(param);
});
}
}
const $off = function(eventName,callback){
if(eventList[eventName]){
if(callback){
let index = eventList[eventName].indexOf(callback);
eventList[eventName].splice(index,1);
}else{
eventList[eventName].length = 0;
}
}
}
export default {
$on,
$emit,
$off
}
//在main.js操作引入、在Vue原型上添加
import observer from './observer'
Vue.prototype.$observer = observer;
-
传递数据
<template>
<div class="box">
<h1>组件5</h1>
<button @click="sendData">向组件6传值</button>
</div>
</template>
<script>
export default {
methods: {
sendData(){
this.$observer.$emit('getVal','child5组件传递的数据')
}
},
}
</script> -
接收数据
<template>
<div class="box">
<h1>组件6</h1>
<h2>接收组件5中传递的数据 {{val}}</h2>
</div>
</template>
<script>
export default {
data(){
return{
val : ''
}
},
created() {
this.$observer.$on('getVal',(val) => {
this.val = val;
})
},
}
</script>
3:第三种方法 EventBus的使用
//创建event-bus.js文件
import Vue from 'vue';
export const EventBus = new Vue();
-
发送数据
<template>
<div class="box">
<h1>child7组件</h1>
<button @click="sendMsg">向组件8传递数据</button>
</div>
</template>
<script>
import {EventBus} from '../event-bus'
export default {
methods: {
sendMsg(){
EventBus.$emit('getVal','组件7中所传递的数据');
}
},
}
</script> -
接收数据
<template>
<div class="box">
<h1>child8组件</h1>
<h2>接收组件7中的数据:{{val}}</h2>
</div>
</template>
<script>
import {EventBus} from '../event-bus'
export default {
data(){
return {
val :''
}
},
created() {
EventBus.$on('getVal',(val) => {
this.val = val;
})
},
}
</script>