vue组件间的数据传递
最近在用vue做了个项目,觉得组件间的数据传递还是很有必要掌握的,故写下总结,如有不对的地方,望指正!
主要有以下五种方式(其他:$parent, $children)
- 父组件通过Prop向自组件传递数据
- 子组件通过$emit向父组件发射一个事件,并传递数据
- Event Bus
- 父子组件的双向数据绑定
- provide与inject(官方不建议在应用中使用,适合用于组件库开发)
- vuex (不举例)
注意事项:
- Prop是单向绑定的,即当父组件的属性发生变化时,传递给子组件,但是不能反过来。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解
1、父组件通过Prop传递数据给子组件
// 父组件 index.vue
<template>
<div>
<Child :count="count"></Child>
</div>
</template>
<script>
export default {
components: {
Child
},
data() {
return {
count: 1
}
}
}
</script>
// 子组件 child.vue
<template>
<div>
<button type="button">++</button> {{ count }}
</div>
</template>
<script>
export default {
props: {
count: Boolean
}
}
</script>
2、$emit
// 父组件 index.vue
<template>
<div>
<Child @listenChildMsg="receiveChildMsg"></Child>
<p>我是子组件传来的数据:{{ msg }}</p>
</div>
</template>
<script>
export default {
components: {
Child
},
data() {
return {
msg: ''
}
},
methods: {
receiveChildMsg(data) {
this.msg = data
}
}
}
</script>
// 子组件 child.vue
<template>
<div>
<button type="button" @click="sendMsg">发送数据给父组件</button>
</div>
</template>
<script>
export default {
methods: {
sendMsg() {
this.$emit('listenChildMsg', '我是子组件的数据')
}
}
}
</script>
3、Event Bus
这主要用于非父子组件通信,当不复杂的项目中使用,通过建立一个空的公共实例来作为事件总线。
var bus = new Vue()
// 在组件A触发事件
bus.$emit('eventName', data)
// 组件B的钩子中监听组件A的事件
bus.$on('eventName', function(data) {
// ...
})
4、组件间的双向数据绑定
// 父组件 index.vue
<template>
<div>
<Child v-model="value"></Child>
<button type="button" @click="handleReduce"></button>
{{ value }}
</div>
</template>
<script>
// 部分代码省略
export default {
data() {
return{
value: 1
}
},
methods: {
handleReduce() {
this.value--
}
}
}
</script>
// 子组件 child.vue
<template>
<div>
{{ currentValue }}
<button type="button" @click="increase">+1</button>
</div>
</template>
<script>
export default {
props: {
value: Number
},
data() {
return {
currentValue: this.value
}
},
watch: {
value(val) {
this.currentValue = val
}
},
methods: {
increase() {
this.currentValue++
this.$emit('input', this.currentValue)
}
}
}
</script>
5、Provide与Inject
// 父组件 index.vue
<template>
<div>
<child />
</div>
</template>
<script>
// 部分代码省略
export default {
provide () {
return {
app: this
}
},
data() {
return {
msg: '来自父组件的数据'
}
}
}
</script>
// 子组件 child.vue
<template>
<div></div>
</template>
<script>
export default {
inject: ['app'],
mounted () {
console.log(this.app.msg) // 来自父组件的数据
}
}
</script>