1 props传值:
所有的prop都使得其父子组件之间形成了一个单行下行的数据流,父级prop的更新会向下流动到子组件中,但是反过来则不行。这样会防止子组件意外变更父组件的状态,从而导致你的应用数据难以理解。
1.1 父组件向子组件传值:
- ① 先在挂载成功的子组件中,添加props内容
props:{ 'named':String, 'blibli':{ type:String, default:"Bworld" // 当父组件没有给子组件传递该参数时,默认值为default } }
将props里的变量绑定到当前子组件的所需位置 。 - ②父组件中,在挂载子组件时将父组件中的数据传入。形式如:形参=‘实参’或形参=‘实参’,前者是动态传参,后者我所挂载的组件名为"v-hello",父组件在子组件挂载时传入了data中的变量为“tittle”,形式如下
<v-hello :named="title"></v-hello>
。
通过上述的两个步骤就可以完成父组件向子组件传值。
注:我在理解的时候觉得对父组件而言,子组件中定义的props内容就是形参,这样想会好理解 一些。
1.2 在prop中添加参数约束:
简单写法:
-
props:["name","age"]
带约束和默认值:
-
在父组件没有给子组件传值的时候,会使用默认值
props:{
name:{
type:String,
default:"法外狂徒张三"
},
age:{
type:int
}
}
带自检验函数:
props:{
propone:{
validator:function(value){
//这个值必须匹配下列字符串中的一个
return ['success','warning','danger'].indexOf(value)!= -1;
}
}
}
2 非父组件通信:
组件间传值可以利用父组件传值给子组件的props,且父组件可以通过给所挂载的子组件添加
:ref="refsname"
,并用this.$refs.refsname
获取子组件的方法;子组件也可以通过this.$parent
的方式执行父组件的方法。但是这种方式仅限于存在直接子父关系的组件中,因此,当我们遇到非父子组件时,可以利用事件车(一个空的vue对象)作为介质来进传值。
2.1 实现非父组件通信
需要用到$on()
与$emit()
,前者用来监听当前实例上的自定义事件,其回调函数会接收所有传入事件触发函数的参数;后者用来触发前者监听的事件,附件参数都会传递给前者的回调函数。
要进行通信的两个组件是brother1.vue、brother2.vue,事件车在VueEmit.js文件中。
VueEmit.js文件
// 事件车通信时,非父组件之间的通信所需的文件
import Vue from 'vue'
let Eventbus = new Vue();
export default (Eventbus);
brother1.vue
<template>
<div id="brother1">
我是brother1
<br>
<button @click="senddata">事件车通信(非父组件执行,也可以认为是同级组件)</button>
</div>
</template>
<script>
import Eventbus from '../../js/VueEmit'
export default {
name: "brother1",
methods:{
senddata(){
Eventbus.$emit("sendinfo",10);
}
}
};
</script>
brother1.vue
<template>
<div id="brother2">
我是brother1
</div>
</template>
<script>
import Eventbus from '../../js/VueEmit'
export default {
name: "brother2",
data(){
return{
msg:"可以"
}
},
mounted(){
Eventbus.$on("sendinfo",(res)=>{
console.log(res);
})
}
};
</script>
将brother1.vue、brother2.vue挂载在App.vue上,运行后点击按钮,即可让brother1.vue的Eventbus.$emit("sendinfo",10)
触发brother2.vue组件中的Eventbus.$on("sendinfo",(res)=>{ console.log(res); })
,并传入参数10
。
需要注意的是非父组件能通信,必须在要通信的非父组件中引入事件车文件,但是在实际使用中,事件车经过webpack打包后可能会出现局部作用域的情况,导致事件车不能正常通信。
我们可以通过直接将事件车文件引入到main.js中来解决上述问题。甚至可以直接关联给vue对象。