1.父组件向子组件传递数据
-- Props + $emit( )
我们在父组件(Parent.vue)中定义一个 name 数据,通过 v-bind 指令将 name 重命名为 parentName 传递给子组件
<template>
<h1>父组件</h1>
<p>{{ name }}</p>
<Child :parentName="name"></Child>
</template>
<script>
import Child from './Child.vue';
export default {
components: {
Child,
},
data() {
return {
name: '周帅帅'
}
}
}
</script>
我们在子组件(Child.vue)中使用 props 方法接收父组件传递的参数 parentName,除了接收值为数组外,接收值还可以为对象,并且还可以设置默认值
<template>
<div>我是子组件</div>
<p>{{ parentName }}</p>
</template>
<script>
export default {
// 还可以定义接收的类型
// props: { parentName: { type: String, default: '' } }
props: ['parentName'],
}
</script>
2.子组件向父组件传递数据
我们在子组件(Child.vue)中添加 button 按钮, 点击时我们使用 $emit() 的方式将 handleClick 事件重命名为 childMessage 方法传递给父组件
<template>
<div>我是子组件</div>
<p>{{ parentName }}</p>
<button @click="handleClick">按钮</button>
</template>
<script>
export default {
props: ['parentName'],
methods: {
handleClick() {
this.$emit('childMessage', '子组件的值')
}
}
}
</script>
我们在父组件(Parent.vue)接收子组件(Child.vue)传递的 childMessage 方法,并重新命名为 parentClick 方法,并将子组件传递在 $event 的值赋值给 name,这样我们发现父组件中的 name 值发生了改变。
<template>
<h1>父组件</h1>
<p>{{ name }}</p>
<Child :parentName="name" @parentClick="childMessage"></Child>
<!-- 下面的这行代码和上面代码意思是一样的 -->
<!-- <Child :parentName="name" @childMessage="name = $event"></Child> -->
</template>
<script>
import Child from './Child.vue';
export default {
components: {
Child,
},
data() {
return {
name: '周帅帅'
}
},
methods: {
parentClick($event) {
this.name = $event
}
}
}
</script>
使用回调函数(callback)方式
我们在父组件(Parent.vue)中定义一个 changeMessage 来修改 name 的值,然后将 parentClick 方法和 parentName 的值传递给子组件(Child.vue)
<template>
<h1>父组件</h1>
<div>{{ name }}</div>
<Child :parentName="name" :parentClick="changeMessage"></Child>
</template>
<script>
import Child from './Child.vue';
export default {
components: {
Child,
},
data() {
return {
name: '周帅帅'
}
},
methods: {
changeMessage() {
this.name = 'web前端'
}
}
}
</script>
我们在子组件(Child.vue)通过 props 接收父组件传递的 msg 和 parentClick 方法
<template>
<h1>我是子组件</h1>
<p>{{parentName}}</p>
<button @click="parentClick">按钮</button>
</template>
<script>
export default {
props: ['parentName', parentClick],
}
</script>
这样当我们点击按钮的时候,发现父组件中的 name 和子组件中的 parentName 都会发生改变。
3、$children + $parent
我们在父组件(Parent.vue)通过 this.$children[0].age 获取子组件(Child.vue)中 age 的值并修改为50
<template>
<h1>父组件</h1>
<p>{{ name }}</p>
<Child @click="changeChildAge">按钮</Child>
</template>
<script>
import Child from './Child.vue';
export default {
components: {
Child,
},
data() {
return {
name: '周帅帅'
}
},
methods: {
changeChildAge() {
// 因为子组件可能存在多个,所以加了一个下标0
this.$children[0].age = 50;
}
}
}
</script>
我们在子组件(Child.vue)通过 this.$parent.message 获取父组件中的值,并在子组件中展示出来
<template>
<div>
<div>我是子组件</div>
<p>{{ age }}</p>
<p>{{ parentName }}</p>
</div>
</template>
<script>
export default {
data() {
return {
age: 10
}
},
computed: {
parentName() {
return this.$parent.name
}
}
}
</script>
所以在子组件(Child.vue)中可以显示父组件的 name 值,当父组件中的按钮点击时,子组件(Child.vue)中 age 的值会从10变成50
4、provide + inject
我们在父组件(Parent.vue)里面通过 provide 提供一个 message 的值
<template>
<h1>父组件</h1>
<Child></Child>
</template>
<script>
import Child from './Child.vue';
export default {
components: {
Child,
},
provide: {
name: '周帅帅'
}
}
</script>
子组件(Child.vue)中通过 inject 接收父组件(Parent.vue)中传递的值
<template>
<div>
<h1>子组件</h1>
{{ name }}
</div>
</template>
<script>
export default {
inject: ['name']
}
</script>
这样我们可以在子组件(Child.vue)中看到父组件中定义的 name 值
5、$attrs + $listeners
我们在父组件(Parent.vue)中向子组件(Child.vue)传递 name 和 age,我们在父组件(Parent.vue)中定义了一个 parentName 事件监听器
<template>
<h1>父组件</h1>
<p>姓名:{{ name }}</p>
<p>年龄:{{ age }}</p>
<Child :name="name" :age="age" @parentName="changeName"></Child>
</template>
<script>
import Child from './Child.vue';
export default {
components: {
Child,
},
data() {
return {
name: '周帅帅',
age: 24
}
},
methods: {
changeName() {
this.name = '小夏'
}
}
}
</script>
我们在子组件(Child.vue)中可以通过 $listeners 获取到父组件(Parent.vue)中的 parentName,这样我们就能执行父组件(Parent.vue)中绑定的事件处理函数(changeName)。然后我们在子组件(Child.vue)里面引入孙子组件(GrandChild.vue),将父组件(Parent.vue)传递给子组件(Child.vue)的 name 和 age 通过 v-bind="$attrs" 传递给孙子组件(GrandChild.vue)。
<template>
<div>
<h1>子组件</h1>
<button @click="$listeners.parentName">按钮</button>
// $attrs相当于子组件向孙子组件传递:name="name" :age="age"
<GrandChild v-bind="$attrs"></Child>
</div>
</template>
<script>
import GrandChild from './GrandChild.vue';
export default {
components: {
GrandChild,
},
data() {
return {
}
}
}
</script>
这样我们在孙子组件(GrandChild.vue)中就可以接收子组件(Child.vue)传递过来的 name 和 age 了。然后通过 $attrs.name 和 $attrs.age 来使用。
<template>
<div>
<h1>孙子组件</h1>
<p>姓名:{{ $attrs.name }}</p>
<p>年龄:{{ $attrs.age }}</p>
</div>
</template>
<script>
export default {
data() {
return {
// 如果不加这个属性,我们发现div中会携带name和age这两个属性
inheritAttrs: false
}
}
}
</script>
6、ref 我们在父组件(Parent.vue)中给引入子组件(Child.vue),并且给子组件(Child.vue)中定义一个 ref 为childName 的值。
<template>
<h1>父组件</h1>
<Child ref="childName"></Child>
<button @click="changeName">按钮</button>
</template>
<script>
import Child from './Child.vue';
export default {
components: {
Child,
},
methods: {
changeName() {
console.log('修改前', this.$refs.childName.name)
this.$refs.childName.changeName()
console.log('修改后', this.$refs.childName.name)
}
}
}
</script>
我们在子组件(Child.vue)中定义一个 changeName 的方法
<template>
<div>
<h1>子组件</h1>
</div>
</template>
<script>
export default {
data() {
return {
name: '周帅帅'
}
},
methods: {
changeName() {
this.name = '前端程序员'
}
}
}
</script>
这样当我们点击父组件(Parent.vue)中的按钮时,我们在浏览器的控制台就可以看到打印的值发生了变化。
几种父子传递方法的区别
props
props 只能用于父组件传递给子组件的时候区使用。
provide与inject?
我们使用 provide 和 inject 进行传值可以在父子组件中传递,也可以将父子组件的传递的值在孙子组件中接收,例子在下面。
举个例子
父组件(Parent.vue)里调用了子组件(Child.vue),同时子组件(Child.vue)里调用了孙子组件(GrandChild.vue)
区别
父组件(Parent.vue)可以用 props 方法直接传数据给子组件(Child.vue),但不能传数据给孙子组件(GrandChild.vue)
父组件(Parent.vue)可以用 provide 与 inject 方法直接传递数据给子组件(Child.vue),也可以直接给孙子组件(GrandChild.vue)
发表评论: