vue组件间的数据传递

443 阅读1分钟

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>