• VUE2 组件间传值


    概述

    常见使用场景可以分为三类:

    • 父子通信:
      • 父向子传递数据是通过 props
      • 子向父是通过 events( $emit )
      • 通过父链 / 子链也可以通信( $parent / $children )
      • ref 也可以访问组件实例;provide / inject API。
    • 兄弟通信:Bus;Vuex;
    • 跨级通信:Bus;Vuex;provide / inject API、 a t t r s / attrs/ attrs/listeners

    props/$emit

    父组件中的数据在子组件中不能直接使用,要想在子组件中使用,步骤:
    1、 父组件中调用子组件时绑定动态属性
    2、 子组件中通过props接收父组件中传递过来的数据
    3、 在子组件中使用

    示例:父组件向子组件传递数据

    • 子组件
    <template>
      <div>
        <h1>子组件</h1>
        <h3>插值表达式获取到:{{msg1}}</h3>
        <h3>插值表达式获取到:{{msg2}}</h3>
        <h3>插值表达式获取到:{{msg3}}</h3>
      </div>
    </template>
    <script>
      export default {
        name: 'Child',
        props: ['msg1', 'msg2', 'msg3']
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 父组件:
    <template>
      <div>
        <h1>父组件</h1>
        <h-child v-bind:msg1="'来自父组件的数据'"    动态绑定
    		:msg2="'data from parent'"   动态绑定的简写形式
    		msg3="'data from parent'"   绑定字符串
    	></h-child>
      </div>
    </template>
    <script>
      // 引入子组件
      import HChild from './Child'
      export default {
        name: 'Parent',
        components: {
          HChild
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    结果:
    在这里插入图片描述

    在子组件中使用props除了可以获取父组件的值之外,还可以验证父组件传递到子组件的数据的合法性,还可以获取父组件本身或者调用父组件中的方法。
    示例:父组件向子组件传递数据

    • 父组件
    <template>
      <div>
        <h1>父组件</h1>
        <h-child v-bind:msg="'来自父组件的数据'"		绑定数据
                 :pfun="fun"				绑定方法
                 :pComp=this				绑定对象
        ></h-child>
      </div>
    </template>
    <script>
      // 引入子组件
      import HChild from './Child'
      export default {
        name: 'Parent',
        components: {
          HChild
        },
        methods: {
          fun () {
            console.log('parent fun')
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 子组件
    <template>
      <div>
        <h1>子组件</h1>
        <h3>插值表达式获取到:{{msg}}</h3>
        <button @click="pfun">调用父组件的方法</button>
        <br>
        <button @click="cfun">获取父组件</button>
      </div>
    </template>
    <script>
      export default {
        name: 'Child',
        props: {
          msg: {
            type: String,
            default: ''
          },
          pfun: {
            type: Function
          },
          pComp: {
            type: Object
          }
        },
        methods: {
          cfun () {
            console.log(this.pComp)
    this.pComp.fun()
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 结果
      在这里插入图片描述

    示例:子组件向父组件传递数据
    子组件向父组件传值一般通过事件触发实现。

    • 子组件
    <template>
      <div>
        <h1>子组件</h1>
        <button @click="passMsg">子组件向父组件传值</button>
      </div>
    </template>
    <script>
      export default {
        name: 'Child',
        methods: {
          passMsg () {
            this.$emit('showMsgEvent', '子组件向父组件传递的值')
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 父组件
    <template>
      <div>
        <h1>父组件</h1>
        <h3>插值表达式获取到:{{msg}}</h3>
        <h-child  @showMsgEvent="showMsg"></h-child>
      </div>
    </template>
    <script>
      // 引入子组件
      import HChild from './Child'
      export default {
        name: 'Parent',
        data () {
          return {
            msg: ''
          }
        },
        components: {
          HChild
        },
        methods: {
          showMsg (val) {
            this.msg = val
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    结果:
    在这里插入图片描述

    单击按钮后
    在这里插入图片描述

    $parent/children

    p a r e n t s 是 当 前 组 件 树 的 根 V u e 实 例 。 如 果 当 前 实 例 没 有 父 实 例 , 此 实 例 将 会 是 其 自 己 。 既 然 可 以 获 取 到 组 件 的 实 例 , 那 么 就 可 以 调 用 组 件 的 属 性 或 是 方 法 进 行 操 作 。 换 句 话 说 即 p a r e n t s 让 我 们 可 以 在 子 组 件 中 访 问 到 父 组 件 的 d a t a 和 方 法 。 具 体 语 法 为 : t h i s . parents是当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。 既然可以获取到组件的实例,那么就可以调用组件的属性或是方法进行操作。换句话说即parents让我们可以在子组件中访问到父组件的data和方法。具体语法为: this. parentsVueparents访datathis.parent.数据
    this.$parent.方法

    示例:父组件向子组件传值:子组件主动获取父组件的数据和方法
    
    • 1
    • 父组件:
    <template>
      <div>
        <h1>父组件</h1>
        <h-child></h-child>
      </div>
    </template>
    <script>
      // 引入子组件
      import HChild from './Child'
      export default {
        name: 'Parent',
        components: {
          HChild
        },
        data () {
          return {
            msg: 'data from parent'
          }
        },
        methods: {
          fun () {
            console.log('parent fun')
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 子组件:
    <template>
      <div>
        <h1>子组件</h1>
        <button @click="showParent">调用父组件的数据和方法</button>
      </div>
    </template>
    <script>
      export default {
        name: 'Child',
        methods: {
          showParent () {
            // 获取到所有的子组件
            console.log(this.$parent)
            // 获取指定子组件中的指定数据
            console.log(this.$parent.msg)
            // 调用子组件的方法
            this.$parent.fun()
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意:子组件获取父组件中的数据的方法的代码不能直接写在钩子函数mounted中。
    结果:
    在这里插入图片描述

    示例:子组件向父组件传值

    • 子组件:
    <template>
      <div>
        <h1>子组件</h1>
      </div>
    </template>
    <script>
      export default {
        name: 'Child',
        data () {
          return {
            msg: 'msg from child'
          }
        },
        methods: {
          fun () {
            console.log('child fun')
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 父组件:
    <template>
      <div>
        <h1>父组件</h1>
        <h-child></h-child>
      </div>
    </template>
    <script>
      // 引入子组件
      import HChild from './Child'
      export default {
        name: 'Parent',
        components: {
          HChild
        },
        mounted () {
          // 获取到所有的子组件,结果是一个数组
          console.log(this.$children)
          // 获取指定子组件中的指定数据
          console.log(this.$children[0].msg)
          // 调用子组件的方法
          this.$children[0].fun()
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    注意:

    • $children并不保证顺序,也不是响应式的。使用 $children 来进行数据绑定时,可以考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源
    • $children 是一个数组,是直接儿子的集合,儿子里面有个 _uid 属性,可以知道它是第几个元素,_uid是元素的唯一标识符,根据这个属性,我们可以进行其他的操作
      结果
      在这里插入图片描述

    $ref:父组件主动获取子组件的数据和方法

    $refs 让我们可以在父组件中进行操作子组件的数据以及方法,使用步骤:

    1. 在父组件中调用子组件时定义一个ref
    2. 在父组件中通过this.$refs.<ref中定义的子组件名>.属性/方法

    示例:子组件向父组件传值:

    • 子组件:
    <template>
      <div>
        <h1>子组件</h1>
      </div>
    </template>
    <script>
      export default {
        name: 'Child',
        data () {
          return {
            msg: 'msg from child'
          }
        },
        methods: {
          fun () {
            console.log('child fun')
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 父组件:
    <template>
      <div>
        <h1>父组件</h1>
        <h-child ref="children"></h-child>
      </div>
    </template>
    <script>
      // 引入子组件
      import HChild from './Child'
      export default {
        name: 'Parent',
        data () {
          return {
            msg: 'data from parent'
          }
        },
        components: {
          HChild
        },
        mounted () {
          // 获取到所有的子组件,结果是一个对象
          console.log(this.$refs.children)
          // 获取指定子组件中的指定数据
          console.log(this.$refs.children.msg)
          // 调用子组件的方法
          this.$refs.children.fun()
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    结果
    在这里插入图片描述

    兄弟组件之间传值

    原理事件广播方式,步骤:
    1、 新建一个js文件,然后引入vue并实例化,最后暴露这个实例
    2、 在广播和接收广播的组件中都引入上步中定义的实例
    3、 通过 e m i t ( ) 广 播 数 据 4 、 通 过 emit()广播数据 4、 通过 emit()广4on()接收数据

    示例:

    • App.vue
    <template>
      <div id="app">
        <v-home></v-home>
        <v-news></v-news>
      </div>
    </template>
    <script>
      import Home from './views/Home';
      import News from './views/News';
      export default {
        name: 'app',
        components:{
          'v-home':Home,
          'v-news':News
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 在src/utils目录中创建bus.js文件,代码如下:
    import Vue from 'vue';  //1、引入一个空的Vue实例
    export default new Vue();   //2、实例化Vue实例并暴露出去
    
    • 1
    • 2
    • Home.vue
    <template>
      <div>
        <h2> Home首页 </h2><br>
        <button @click="broadcast2News">给News广播数据</button>
      </div>
    </template>
    <script>
      import bus from '../utils/bus'
      export default {
        methods: {
          broadcast2News(){//广播数据
            bus.$emit('data2news', '来自Home的数据');
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • News.vue
    <template>
      <div>
        <h2> News头部</h2><br>
      </div>
    </template>
    <script>
      import bus from '../src/bus'
      export default {
        mounted(){
          bus.$on('data2news',function (shuJu) {
            console.log(shuJu);
          });
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    结果:
    在这里插入图片描述

    a t t r s / attrs/ attrs/listeners:多级组件间传值

    • $attrs:将父组件中不包含props的属性传入子组件,通常配合interitAttrs选项一起使用
    • $listeners:监听子组件中数据的变化,传递给父组件

    示例:$attrs
    第一步:App.vue

    <template>
      <div id="app">
        <h2>最外层组件</h2>
        <!-- 统一传值 -->
        <v-parent :msgA="msg1" :msgB="msg2" :msgC="msg3"></v-parent>
      </div>
    </template>
    <script>
      // 引入子组件
      import Parent from './views/Parent'
      export default {
        name: 'Parent',
        components: {
          'v-parent': Parent
        },
        data () {
          return {
            msg1: 'aaaaa',
            msg2: 'bbbbb',
            msg3: 'ccccc'
          }
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    第二步:Parent.vue

    <template>
      <div>
        <h2>中间组件</h2>
        <h-child v-bind="$attrs"></h-child>
      </div>
    </template>
    <script>
      // 引入子组件
      import HChild from './Child'
      export default {
        name: 'Parent',
        components: {
          HChild
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    第三步:Child.vue

    <template>
      <div>
        <h2> 数据接收方 </h2><br>
      </div>
    </template>
    <script>
      export default {
        mounted () {
          console.log(this.$attrs)
        }
      }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    结果:
    在这里插入图片描述

  • 相关阅读:
    零代码编程:用ChatGPT批量下载podomatic播客RSS页面音频
    XHTML基础知识了解
    论文解读(GRACE)《Deep Graph Contrastive Representation Learning》
    csdn,是时候说再见!
    搜索二叉树-key模型
    echarts设置竖向不同区间范围颜色,并且x轴自定义轴线刻度范围
    spring security(二)--授权
    Android图形-架构2
    Flink中序列化RoaringBitmap不同方式的对比
    selenium不定位元素直接使用键盘操作(如弹框操作)
  • 原文地址:https://blog.csdn.net/lianghecai52171314/article/details/125612306