Vue 组件之间的传值方式有哪些?
在平常写Vue项目时,组件传值必不可少,今天我们就要总结一下有哪些种方式呢?
1、父组件向子组件传值(用props)
子组件
<template>
<div>
<ul>
<li v-for="user in users" :key="user">{{user}}</li>
<!-- 遍历传递过来的值,然后呈现到页面 -->
</ul>
</div>
</template>
<script>
export default {
name:"testComponent",
props:{
users:{ type:Array }
},
}
</script>
父组件
<template>
<div>
<!-- 父组件向子组件传值(用props) -->
<testComponent :users="users"></testComponent>
</div>
</template>
<script>
import testComponent from "@/components/testComponent.vue"
export default {
components:{testComponent},
data(){
return {
users:["Henry","Bucky","Emily"],
}
},
}
</script>
2、子组件传值给父组件,子组件使用 $emit+事件 对父组件进行传值
子组件
<template>
<div>
<span @click="changeTitle">{{title}}</span>
</div>
</template>
<script>
export default {
name:"testComponent",
data(){
return {
title:"测试子组件向父组件传值"
}
},
methods:{
changeTitle(){
// 子组件传值给父组件,子组件使用$emit+事件对父组件进行传值
this.$emit("titleChanged",'子向父组件传值') //自定义事件 传递值“子向父组件传值”
}
}
}
</script>
父组件
<template>
<div>
<testComponent @titleChanged="updateTitle"></testComponent>
<h4>{{title}}</h4>
</div>
</template>
<script>
import testComponent from "@/components/testComponent.vue"
export default {
components:{testComponent},
data(){
return {
title:"原始标题"
}
},
methods:{
updateTitle(e){
this.title = e
}
}
}
</script>
3、组件中可以使用 $parent和 $children获取到父组件实例和子组件实例,进而获取数据
$parent 当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。
$children 当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。
4、使用 $attrs和 $listeners,在对一些组件进行二次封装时可以方便传值,例如A->B->C
$attrs 简单来说就是 组件向下传递数据 的,是props通信的补充方案,避免了组件中props过多的窘境。
使用场景 : 在孙子或更深层后代组件访问祖辈组件中的数据
举例 :
祖父组件 GrandPa
<template>
<div>
我是祖父: 下面是爸爸
<Parent v-bind="$attrs" :name="'爸爸'" :age="age" :sex="sex" />
</div>
</template>
<script>
import Parent from "./Parent.vue"
export default {
name: "GrandPa",
components: {Parent},
data() {
return {
age: 65,
sex: '男'
}
}
}
</script>
父亲组件 Parent
<template>
<div>
我是爸爸:叫 {{ name }}, 下面是儿子
<Son :name="'佩奇'" />
</div>
</template>
<script>
import Son from "./Son.vue"
export default {
name: "Parent",
components: {
Son
},
props: {
name: {
type: String,
default: ""
}
},
data() {
return {
age: 40,
gender: '男'
}
},
created() {
// GrandPa 祖父组件传的数据 {age: 65,sex: '男'} 就在attrs里
console.log(this.$attrs);
}
}
</script>
儿子组件
<template>
<div>
我是儿子:叫{{ name }}
</div>
</template>
<script>
export default {
name: "Son",
props: {
name: {
type: String,
default: ''
}
},
data() {
return {
age: 18,
sex: '男'
}
},
created() {
console.log(this.$attrs);
}
}
</script>
如果要通过$attrs访问父组件数据,在父组件使用Son组件时吧数据传进来即可,那如果要访问祖父组件GrandPa的数据呢?在Parent组件中使用儿子组件时加上 v-bind=" $attrs " 即可。
<template>
<div>
我是爸爸:叫 {{ name }}, 下面是儿子
<Son v-bind="$attrs" :name="'佩奇'" />
</div>
</template>
$listeners : 简单来说就是组件跨代传递函数的桥梁
使用场景 : 在孙子或更深层后代组件访问祖辈组件中定义的函数
和
a
t
t
r
s
差
不
多
,
attrs 差不多,
attrs差不多,attrs监听的是传递的数据, listeners 是监听的 祖辈组件里定义的函数