1、父传子 props
父组件:使用propsName="dataName"
提供数据,其中dataName
可以是一个常量值,也可以是data和computed中的属性,当使用data和computed时
子组件
<template>
<div class="father">
<h1>这是father组件</h1>
<!-- 这里传递的是固定值 -->
<!-- <Son fatherToSon="fatherToSon" />-->
<!-- 这里绑定了data中的值 -->
<Son :fatherToSon="fatherToSon" />
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components:{
Son
},
data(){
return {
fatherToSon:1,
}
}
</script>
<style scoped>
</style>
子组件在props里接收父组件传递来的值就可以和data中的值一样使用了
props可以有数组形式和对象形式:
数组形式中每个数组元素是字符串,对应了父组件传来的变量名,也就是上面提到的propsName
;
使用对象形式时也分为两种情况:
1、props:{propsName1:变量类型,propsName2:变量类型}
,就是下面的代码写法;
2、对象嵌套
props:{
propsName1:{
type:变量类型1,
default:变量默认值1
},
propsName2:{
type:变量类型2,
default:变量默认值2
}
}
子组件代码
<template>
<div class="son">
<h1>这是son组件</h1>
<span>来自father的值(fatherToSon):{{fatherToSon}}
</span>
</div>
</template>
<script>
export default {
name: "Son",
props: {
//在这里接收值
fatherToSon: Number,
}
</script>
<style scoped>
</style>
2、祖先组件传递到子组件 provide + inject
provide用于在祖先组件提供数据,同样的可以是固定的值,也可以是data或computed中的属性
provide:{
provideParams:'变量值'
}
inject用于接收
inject:['provideParams']
这里篇幅原因就不展示GrandPa和Father的代码了,嵌套关系如下:
祖先(Ancestors)->祖父(GrandPa)->父(Father)->子(Son)
祖先组件 Ancestors.vue
<template>
<div class="ancestors">
<h1>这是祖先组件</h1>
</div>
</template>
<script>
import GrandPa from './GrandPa'
export default {
name: "Ancestors",
provide(){
return {
provideFromAncestors:'ancestors'
}
},
components:{
GrandPa
},
data(){
return{
}
}
</script>
<style scoped>
</style>
子组件代码 Son
<template>
<div class="son">
<h1>这是son组件</h1>
<p>来自ancestors的值:{{provideFromAncestors}}</p>
</div>
</template>
<script>
export default {
name: "Son",
inject:['provideFromAncestors'],
props: {
fatherToSon: Number,
}
}
</script>
<style scoped>
</style>
3、使用$children和$refs访问子组件
$refs
使用$ref
时,需要先在子组件或DOM节点上绑定ref属性,比如son,然后使用this.$refs.son
或this.$refs["son"]
访问该节点
父组件
<template>
<div class="father">
<h1>这是father组件</h1>
<button @click="showRef">$ref访问子组件</button>
<Son ref="son" />
<br>
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components: {
Son
},
methods: {
showRef(){
console.log(this.$refs.son);
}
}
}
</script>
<style scoped>
</style>
子组件
<template>
<div class="son">
<h1>这是son组件</h1>
</div>
</template>
<script>
export default {
name: "Son",
data(){
return {
sonData:1
}
},
methods: {
sonMethods(){
}
}
}
</script>
<style scoped>
</style>
可以看到打印出的$refs['son']
的结果时一个vue实例,上面包含了组件上的data、methods等方法和属性
$children
$children可以访问到当前组件下的所有子组件,这些组件构成一个数组
<template>
<div class="father">
<h1>这是father组件</h1>
<button @click="showRef">$ref访问子组件</button>
<Son ref="son" />
<Son/>
<br>
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components: {
Son
},
methods: {
showRef(){
console.log(this.$refs.son);
console.log(this.$children);
}
}
}
</script>
<style scoped>
</style>
可以看到返回一个数组,里面两个对象对应了两个Son组件
父组件、祖先组件到子组件传值内容就这些,其中$eventDispatch作为$children的拓展,并不是父-子的过程,而是子-父的过程。
4、使用$children递归向下传递
当某个父组件调用$eventBroadCast时,会递归其每一个子组件,当子组件绑定了对应的event时,会触发对应的函数执行
Vue.prototype.$eventBroadCast = function (event, value) {
let cpn = this
const cb = (c) => {
if (!c.$children){
return
}
c.$children.map((c) => {
c.$emit(event, value)
cb(c)
})
}
cb(cpn)
}
举例:Ancestors向下广播事件ancestorsBroadcast
<template>
<div class="ancestors">
<h1>这是祖先组件</h1>
<button @click="ancestorsBroadcast">祖先组件通知其他子组件</button>
</div>
</template>
<script>
import GrandPa from './GrandPa'
export default {
name: "Ancestors",
components:{
GrandPa
},
methods:{
ancestorsBroadcast(){
this.$eventBroadCast('ancestorsBroadcast',123)
}
}
}
</script>
<style scoped>
</style>
在Father上进行监听。
这里递归到了son这个子组件上,通过son.$emit,使得father组件对应的函数执行
<template>
<div class="father">
<h1>这是father组件</h1>
<p>来自ancestors的值:{{provideFromAncestors}}</p>
<button @click="showRef">$ref访问子组件</button>
<Son @ancestorsBroadcast="ancesterBroadCastToSon"
/>
<Son/>
<br>
</div>
</template>
<script>
import Son from './Son'
export default {
name: "Father",
components: {
Son
},
},
methods: {
cesterBroadCastToSon(value) {
console.log(`ancester通知到Son,值为${value}`)
}
}
}
</script>
<style scoped>
</style>
同样的,可以在GrandPa上进行监听
<template>
<div>这是grandPa组件
<Father @ancestorsBroadcast="ancesterBroadCastToFather" />
</div>
</template>
<script>
import Father from "./Father";
export default {
name: "GrandPa",
components: {Father},
methods: {
ancesterBroadCastToFather(value) {
console.log(`ancester通知到Father,值为${value}`)
}
}
}
</script>
<style scoped>
</style>
上级到下级的通信基本就可这些了。事件总线放到下篇再讲吧