vue 父子组件间的数据传递

1,634 阅读2分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

一、父子组件间传值[props]

  1. 【重点】 父组件向子组件传递数据:通过属性传递数据;子组件通过props接收数据。
<div id="root">
       <counter :count="0"></counter>
</div>
var counter = {
        props: ['count'],
        template: '<div>{{count}}</div>'
}

var vm = new Vue({
        el: "#root",
        components:{
                counter: counter
        }	
})

父组件通过属性的形式 向子组件传递一个名为 xxx 的数据;

子组件使用props接收这个数据,即props: ['xxx'],子组件在模板template使用传过来的数据。

二、子组件向父组件传值 (通过事件形式($emit)传值 )

场景需求: 实现一个计数器,每一次都增加2,并求和。

问题要求: 让子组件每次点击时,调用父组件的求和方法。

实现方法: 子组件向父组件传值,通过事件的形式,即this.$emit('事件' , 步长) 来告知父组件新增的参数值;父组件则在页面模板的dom标签添加一个监听事件,即 @事件名="执行方法名",那么一旦子组件做了修改,在父组件就能监听到其改变,在页面就会做出相应的改变。

<div id="root">
        <counter :count="0" @add="handleAdd"></counter>+
        <counter :count="0" @add="handleAdd"></counter>=
        <div>{{total}}</div>
</div>
var counter = {
    props: ['count'],
    template: '<div @click="handleClick">{{count}}</div>',
    methods: {
            handleClick: function() {
                    this.number = this.number + 2,
                            this.$emit('add', 2)
            }
    }
}
var vm = new Vue({
    el: "#root",
    data: {
            total: 0
    },
    components: {
            counter: counter
    },
    methods: {
            handleAdd: function(step) {
                    this.total += step
            }
    }
})

问题分析: 当点击数值时并没有实现自增2的功能,这是因为子组件中不要直接修改父组件传递过来的数据

涉及知识点: Vue单向数据流。父组件可以向子组件通过属性形式传递参数,传递的参数也可以随时随意修改;但子组件不能修改父组件传递过来的参数。!!!只能用父组件传递的数据!!!

原因: 因为子组件接收父组件传递过来的数据,并不是一个基础类型的数据类型,而是类似于object这种引用类型的数据类型。如果修改了引用类型的数据,在使用子组件时,则会造成其他子组件接收数据的错误。

解决单向数据流问题: 子组件接收到父组件的数据,将接收到的数据复制一份放在子组件定义的data里number(相当于这个数据的副本)。那么就能让子组件使用自己data里的number,进而在子组件的methods里就使用 this.number ++来实现累加数据的功能。

var counter = {
        props: ['count'],
        data: function() {
                return {
                        number: this.count
                }
        },
        template: '<div @click="handleClick">{{number}}</div>',
        methods: {
                handleClick: function() {
                        this.number = this.number + 2,
                                this.$emit('add', 2)
                }
        }
}

三、Vue单向数据流与双向数据绑定

其实,这两个是不同的概念,双向绑定是model改变view自动更新,view改变model自动更新;而单向数据流指的父组件传值给子组件,子组件不能修改这个值,而父组件修改这个值的话子组件也会受影响,这个影响是单向的,只能从父组件流向子组件,不能反向。

1、单向数据流

单向数据流的意思是指数据的改变只能从一个方向修改,指的是组件之间的数据流动。

举个栗子:如一个父组件有两个子组件,分别为1和2。父组件向子组件传递数据,两个组件都接收到了父组件传递过来的数据,在组件1中修改父组件传递过来的数据,子组件2和父组件的值不会发生变化。这就是单向的数据流,子组件不能直接改变父组件的状态。但是如果父组件改变相应的数据,两个子组件的数据也会发生相应的改变。

2、双向数据绑定

由MVVM框架实现,MVVM的组成:View,ViewModel,Model。其中View 和 Model不能直接通信,要通过ViewModel来进行通信。

举个栗子:例如,当Model部分数据发生改变时,由于vue中Data Binding将底层数据和Dom层进行了绑定,ViewModel通知View层更新视图;当在视图 View数据发生变化也会同步到Model中。View和Model之间的同步完全是自动的,不需要人手动的操作DOM。