到了Vue2.x有哪些变化?—— 组件通信

一、父子组件传递数据

默认情况下父子组件的数据是不共享地

推荐一个Vue辅助工具 —— vue-devtool下载ps:具体查看请参照vue-devtools安装

1. 子组件获取父组件数据(儿子获取父亲数据)

通过选项对象中的props,也就是下面的数据传输过程:


知识点(关于props):

  //方式一:用数组的方式
  props:['m','myMsg']
  //方式二:用json的形式,也就是给数据定义一个数据类型
  props:{
     m': String,
    'myMsg': Number
  }

之前在Vue1.x中,子组件可以更改父组件信息(数据),可以是同步的sync(:msg.sync="父组件数据名")。在利用props获取父级数据的时候加上sync

//注意这个是Vue1.x版本
<body>
    <template id="child">
        <div>
            <h3>我是子组件</h3>
            <input type="button" value="点我" @click="change" />
            <strong>{{ msg }}</strong>
        </div>
    </template>
    <div id="app">
        父级:{{ a }}
        <child-com :msg.sync="a"></child-com>   <!-- 只需要这里设置同步 -->
    </div>
</body>
<script src="vue1.0.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            a:'我是父组件内的数据'
        },
        components: {
            'child-com': {
                props:['msg'],
                template:'#child',
                methods:{
                    change() {
                        this.msg = '点击我更改数据了'
                    }
                }
            }
        }
    });
</script>

现在Vue2.x,子组件不能直接给父组件数据直接赋值操作(也就是直接修改数据),因为当项目大的时候一个子组件数据更改会引发一系列问题就很麻烦。

但是我们在项目中往往会需要某个子组件更改父组件内数据。这里请看下面

** 父组件每次传一个对象给子组件,利用元素js中对象是引用的(在内存中共用一块地址)**

<body>
    <template id="child">
        <div>
            <h3>我是子组件</h3>
            <input type="button" value="点我" @click="change" />
            <strong>{{ msg.a }}</strong>
        </div>
    </template>
    <div id="app">
        父级:{{ giveData.a }}
        <child-com :msg="giveData"></child-com> <!-- 这里把父组件的json数据传给子组件 -->
    </div>
</body>
<script src="vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            giveData: {
                a:'我是父组件内的数据'
            }
        },
        components: {
            'child-com': {
                props:['msg'],
                template:'#child',
                methods:{
                    change() {
                        this.msg.a = '点击我更改数据了';//这里更改子组件的某一项数据,父组件就跟着改了
                    }
                }
            }
        }
    });
</script>

如图当点击按钮更新子组件数据后:


2. 父组件获取子组件数据(父亲获取儿子数据)

原理:*子组件主动把自己的数据通过$emit(),发送到父级,父组件的模板中有个“事件”,父组件接收的时候用的是“@”(是自定义事件,若有子级数据发送就会触发)

子级:vm.$emit(事件名,数据);
父级: v-on:xxx="xxx" <===> @xxx="xxx"

Ex代码:
<body>
    <div id="box">
        <com-a></com-a>
    </div>
    <template id="testA">
        <div>
            <span>我是父级 => {{msg}}</span>
            <com-b @child-msg="get"></com-b> <!-- 这个首先就是子组件的展示区,其次在挂载自定义事件,当子组件有数据发送的时候就会触发 -->
        </div>
    </template>
    <template id="testB">
        <div>
            <span>子组件</span><input type="button" value="发送数据" @click="send" />
        </div>
    </template>
<script src="vue.js"></script>
<script>
    var comA = {
        data() {
            return {
                msg:'',
            }
        },
        template:'#testA',
        methods:{
            get(data){ //这里面接收到的参数就是子组件发送的数据
                alert(data);
                this.msg = data;
            }
        },
        components:{
            'comB': {
                data(){
                    return {
                        b:'我是子组件的数据'
                    }
                },
                template:'#testB',
                methods:{
                    send(){
                        this.$emit('child-msg',this.b); //这里就是把子组件的b数据通过$emit()方法发送出去
                    }
                }
            }
        }
    }
    var vm=new Vue({
        el:'#box',
        components:{
            comA  //这里等价于 <==> 'comA':comA
        }
    });
</script>

点击子组件发送数据按钮后如下:


3. 兄弟组件之间获取数据(兄弟之间)

首先准备一个var Event = new Vue();,用Event身上的方法
其次在需要发送数据的组件上:Event.$emit(事件名称,数据)
再次在需要接收数据的组件上:
Event.$on(事件名称,function(data){ //data }.bind(this))

Ex代码:把组件A和组件B的数据传到组件C上
<body>
    <div id="app">
       <com-a></com-a>
       <com-b></com-b>
       <com-c></com-c>
    </div>
</body>
<script src="vue.js"></script>
<script type="text/javascript">
    //准备一个空的实例对象,就要它身上的方法
    var Event = new Vue();//全局的
    var A = {
        template: `
            <div>
                <span>我是A组件 => {{ a }}</span>
                <input type="button" value="A数据传给C" @click="send" />
            </div>
        `,
        data() {
            return{
                a:'我是a数据'
            }
        },
        methods:{
            send(){
                Event.$emit('a-msg',this.a);
            }
        }
    }
    var B = {
        template: `
            <div>
                <span>我是B组件 => {{ b }}</span>
                <input type="button" value="B数据传给C" @click="send" />
            </div>
        `,
        data() {
            return{
                b:'我是b数据'
            }
        },
        methods:{
            send(){
                Event.$emit('b-msg',this.b);
            }
        }
    }
    var C = {
        template:`
            <div>
                <h3>我是C组件</h3>
                <span>接收过来的A的数据 => {{ a }}</span>
                <br />
                <span>接收过来的B的数据 => {{ b }}</span>
            </div>
        `,
        data() {
          return{
              a:'',
              b:''
          }
        },
        mounted() {
            alert('C组件加载完毕');
            //var _this = this;
            //接收a组件的数据
            Event.$on('a-msg',function (a) {
                alert(a);//拿到a数据
                this.a = a;
            }.bind(this));//需要绑定给函数
            var _this = this;
            //接收b组件的数据
            Event.$on('b-msg',function (b) {
                alert(b);//拿到b数据
                _this.b = b;
            });
        }
    }
    var vm = new Vue({
        el: '#app',
        components: {
            'com-a':A,
            'com-b':B,
            'com-c':C
        }
    });
</script>

当点击传输A数据给C和传输B数据给C结果如下:


预告——下面将会说Vue2.x中动画(transition)的那些变化。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容