• Web全栈探索,Vue基础系列,组件化开发(三)组件之间的数据交互


    一、父组件向子组件传值

    步骤1.父组件通过属性将值传递给子组件

    //静态传递
    <div 属性名="来自父组件的数据"></div>
    
    
    //动态绑定获取
    <div :属性名="存储父组件传递数据的变量"></div>

    步骤2.子组件内部通过props接收父组件传递过来的值

    Vue.component(‘子组件名称', {
        props: ['属性名'],
        template: '<div>{{ 属性名 }}</div>'
    })

    示例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <div id="app">
        <!--父组件使用子组件-->
    
        <!--纯静态可以使用-->
        <son-component key1='来自父组件的值1' key2="来自父组件的值2"></son-component>
        <!--纯动态可以使用-->
        <son-component :key1='infoOne' :key2='infoTwo'></son-component>
        <!--动态、静态可以结合使用-->
        <son-component key1='来自父组件的值' :key2='infoTwo'></son-component>
    </div>
    <script type="text/javascript" src="../../js/vue.js"></script>
    <script type="text/javascript">
    
        // 定义子组件
        // 其中 key1、key2 两个属性为父组件的属性,并且这两个属性的值都会被子组件接收
        Vue.component('son-component', {
            props: ['key1', 'key2'],
            data: function() {
                return {
                }
            },
            template: '<div>{{key1 + "-----" + key2}}</div>'
        });
    
        // vue 的实例本身就是一个组件,并且是一个根组件,因此它可以使用任何自定义组件
        let vm = new Vue({
            el: '#app',
            data: {
                msg: '父组件中内容',
                infoOne: '用于给子组件传递数据的绑定变量',
                infoTwo: 'this is the result'
            }
        });
    </script>
    </body>
    </html>
    

    注意事项:

    1.在props中使用驼峰形式,模板中需要使用短横线的形式(dom 元素的属性是不区分大小写的);字符串形式的模板中没有这个限制

    Vue.component(‘component-a', {
    
        // 在 JavaScript 中是驼峰式的
        props: [‘valueData'],
        template: '<div>{{ valueData }}</div>'
    })
    
    
    <!– 在html中是短横线方式的 -->
    <menu-item value-data=“测试数据"></menu-item>

    2.props属性值类型

    • 字符串 String
    • 数值 Number
    • 布尔值 Boolean
    • 数组 Array
    • 对象 Object

    传值的时候,如果采用的是静态传递,则所有的数据都会被当作字符串处理

    传值的时候,如果采用的是动态属性绑定,则数据会按照原值类型处理

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <div id="app">
        <!--动态属性绑定-->
        <component-a :one='one_data' :two='two_data' :three='three_data' :four='four_data' :five='five_data'></component-a>
        <!--静态数据传递-->
        <component-a one='this is the result' two='100' three='true' four='[1, 2, 3, 4, 5]' five="{'id': 1, 'name': 'lanYue'}"></component-a>
    </div>
    <script type="text/javascript" src="../../js/vue.js"></script>
    <script type="text/javascript">
        /*
          父组件向子组件传值-props属性值类型
        */
    
        Vue.component('component-a', {
            props: ['one', 'two', 'three', 'four', 'five'],
            template: `
                <div>
                    <div>{{typeof one}}</div>
                    <div>{{typeof two}}</div>
                    <div>{{typeof three}}</div>
                    <div>{{typeof four}}</div>
                    <div>{{typeof five}}</div>
                </div>
            `
        });
        let vm = new Vue({
            el: '#app',
            data: {
                one_data: 'this is the result',
                two_data: 100,
                three_data: true,
                four_data: [1, 2, 3, 4, 5],
                five_data:{'id': 1, 'name': 'lanYue'}
            }
        });
    </script>
    </body>
    </html>
    

    二、子组件向父组件传值

    1.props传递数据原则

    单向数据流,只允许父组件向子组件传递数据,而不建议子组件直接操作 props 中的数据(虽然允许,但不推荐)

    2.子组件向父组件传递数据方法

    (1).子组件通过自定义事件向父组件传递信息

    $emit("事件名称")

    (2).父组件监听子组件的事件

    <子组件名称 v-on:='事件名称'></子组件名称>

    (3)举例——子组件向父组件传递已有数据(变更后的)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <div id="app">
        <div :style='{fontSize: fontSize + "px"}'>{{msg}}</div>
        <!--父组件需要监听事件时,只需要使用 @ 符号 加上事件的名称即可,等号右边为处理逻辑或者监听成功后要执行的函数-->
        <!--父组件为 key 属性绑定值并且传给子组件-->
        <!--父组件监听 enlarge-text 事件-->
        <!--子组件通过 my_key 属性绑定 key_data数据-->
        <component-a :my_key="key_data" @enlarge-text='handle'></component-a>
    </div>
    <script type="text/javascript" src="../../js/vue.js"></script>
    <script type="text/javascript">
    
        Vue.component('component-a', {
            // 子组件监听 key 属性
            props: ['my_key'],
            // $emit 用于触发自定义事件,参数为事件名称,可以自定义名称
            // 子组件自定义事件,用于向父组件传递数据
            template: `
            <div>
              <button @click='$emit("enlarge-text")'>{{my_key}}</button>
            </div>
          `
        });
        let vm = new Vue({
            el: '#app',
            data: {
                msg: '测试数据',
                key_data: '扩大字体',
                fontSize: 10
            },
            methods: {
                handle: function(){
                    // 扩大字体大小
                    this.fontSize += 5;
                }
            }
        });
    </script>
    </body>
    </html>
    

    (4)举例——子组件向父组件传递新数据

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <div id="app">
        <div :style='{fontSize: fontSize + "px"}'>{{msg}}</div>
        <!--父组件通过 $event 获取子组件传递过来的数据-->
        <component-a :my_key="key_data" @enlarge-text='handle($event)'></component-a>
    </div>
    <script type="text/javascript" src="../../js/vue.js"></script>
    <script type="text/javascript">
    
        /*
          子组件通过 $emit 的第一个参数用于注册事件,第二个参数 用于作为时间的参数向父组件传递数据
        */
        Vue.component('component-a', {
            props: ['my_key'],
            template: `
            <div>
              <button @click='$emit("enlarge-text", 5)'>{{my_key}}</button>
            </div>
          `
        });
        let vm = new Vue({
            el: '#app',
            data: {
                msg: '测试数据',
                key_data: '扩大字体',
                fontSize: 10
            },
            methods: {
                // 父组件得到子组件传递而来的参数
                handle: function(arg){
                    // 扩大字体大小
                    this.fontSize += arg;
                }
            }
        });
    </script>
    </body>
    </html>
    

    三、非父子组件间传值

    非父子组件(一般指兄弟组件)之间传递数据需要用到事件中心,它们之间的关系如下:

    1.具体步骤:

    1. 单独的事件中心(由新 new 的 vue 实例对象扮演)管理组件间的通信

    let 事件中心变量名 = new Vue()

    2. 监听事件与销毁事件

    事件中心变量名.$on('自定义事件名称', '事件函数')
    事件中心变量名.$off('自定义事件名称')

    3. 触发事件

    事件中心变量名.$emit(‘自定义事件名称', 携带任意参数)

    2.示例代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
    <div id="app">
        <div>
            <button @click='handle'>销毁事件</button>
        </div>
        <one-component></one-component>
        <two-component></two-component>
    </div>
    <script type="text/javascript" src="../../js/vue.js"></script>
    <script type="text/javascript">
    
        /*
          兄弟组件之间数据传递
        */
        // 提供事件中心
        let hub = new Vue();
    
        // 注册组件一
        Vue.component('one-component', {
            data: function () {
                return {
                    num: 1
                }
            },
            template: `
                <div>
                    <div>组件一:{{num}}</div>
                    <div>
                        <button @click='handle'>点击加二</button>
                    </div>
                </div>
            `,
            methods: {
                // 组件一自定义 触发组件二变化的 事件二,并传递参数 2
                handle: function () {
                    hub.$emit('two-event', 2);
                }
            },
            mounted: function () {
                // 事件中心监听引发 组件一 变动的事件一
                hub.$on('one-event', (val) => {
                    this.num += val;
                });
            }
        });
    
    
        Vue.component('two-component', {
            data: function () {
                return {
                    num: 2
                }
            },
            template: `
                <div>
                    <div>组件二:{{num}}</div>
                    <div>
                        <button @click='handle'>点击加二</button>
                    </div>
                </div>
            `,
            methods: {
                handle: function () {
                    // 组件二自定义 触发组件一变化的 事件一,并传递参数 2
                    hub.$emit('one-event', 2);
                }
            },
            mounted: function () {
                // 事件中心监听引发 组件二 变动的事件一
                hub.$on('two-event', (val) => {
                    this.num += val;
                });
            }
        });
    
        let vm = new Vue({
            el: '#app',
            data: {},
            methods: {
                handle: function () {
    
                    // 利用事件中心销毁组件一、二的事件
                    hub.$off('one-event');
                    hub.$off('two-event');
                }
            }
        });
    </script>
    </body>
    </html>
    
    作者:蓝月

    -------------------------------------------

    个性签名:能我之人何其多,戒骄戒躁,脚踏实地地走好每一步

  • 相关阅读:
    Kafka学习笔记之kafka高版本Client连接0.9Server引发的血案排查
    机器学习笔记之python实现朴素贝叶斯算法样例
    机器学习笔记之python实现支持向量机SVM算法样例
    机器学习笔记之AdaBoost算法详解以及代码实现
    机器学习笔记之python实现关联规则算法Apriori样例
    机器学习笔记之python实现AdaBoost算法
    F-47(copy 邓大顾)
    js 设置标题 空白
    微信授权验证
    iphone web 时间 问题
  • 原文地址:https://www.cnblogs.com/viplanyue/p/13573723.html
Copyright © 2020-2023  润新知