组件之间传值

  • 父组件向子组件传值使用props,参考:父组件向子组件传值
  • 子组件向父组件传值,主要是以下三个步骤组成:
  1. 在子组件中自定义一个事件,使用 this.$emit('btn-click', item)的语法,emit指代发射事件,btn-click是我们自定义的事件名,item是子组件中的数据。 注意::vue官方推荐你始终使用 kebab-case格式的事件名。
  2. 在父组件中使用v-on监听在子组件中我们自定义的数组,并为其在父组件中定义一个接收监听的事件
  3. 在父组件中接收数据

老规矩,看代码:

    <div id="app">
      <main-view @btn-click="descclick"></main-view>
      <p>分类id:{{ id }} <br>名称name:{{ name }}</p>
    </div>
    
    <template id="desc-view">
      <div>
        <button type="button" @click="itemClick(item)" v-for="item in categorylist">{{ item.name }}</button>
      </div>
    </template>
    
    <script type="text/javascript">
      
      Vue.component('main-view',{
        template:"#desc-view",
        data:function(){
          return{
            message: 'Hello Vue',
            categorylist:[
              {id: 1, name: '生鲜优选'},
              {id: 2, name: '手机数码'},
              {id: 3, name: '家用电器'},
              {id: 4, name: '电脑办公'},
            ]
          }
        },
        methods:{
          // 子组件中定义	
          itemClick: function(item){
            // 发射自定义事件
            this.$emit('btn-click', item)
          }
        }
      });
      
      const app = new Vue({
        el: "#app",
        data:{
          id: '',
          name:''
        },
        methods:{
          // 接收事件,父组件中接收
          descclick:function(item){
            categorylist = ('descclick', item)
            console.log('descclick', item)
            this.id = categorylist.id
            this.name = categorylist.name
          }
        }
      })
    </script>

组件之间的事件传递:

组件之间的事件传递多是通过 $emit$on 来进行的,所以我们需要先来看一下这两个 API 的使用方式。

首先是 vm.$emit( eventName, […args] ),它用于触发当前实例上的事件,第一个参数为被触发事件的名称,第二个参数为传递给被触发事件的参数,可以为多个, 开篇已经说过,也有一个简单的例子。

然后是 vm.$on( event, callback ),它用于在当前实例中创建一个自定义的事件,事件可以由 vm.$emit 触发。第一个参数为事件名称,第二个参数为当事件被触发时执行的回调方法。

这两个方法的使用还是比较简单的,接下来我们就看一下不同的组件之间如何通过这两个方法来进行事件传递。还是以上一章中讲解 props 时用到的代码为例:

  • 提醒:注意props中属性的命名方式,是忽略大小写的,所以大写的属性有可能不能识别!
<div id="app">
    <main-view></main-view>
</div>

<template id="main-view">
    <div>
      <button @click="onChangeDescClick('Android')">Android</button>
      <button @click="onChangeDescClick('IOS')">IOS</button>
      <button @click="onChangeDescClick('Vue')">Vue</button>
      <button @click="onDescFontSizeClick()">DescFontSize++</button>

      <desc-view :pushSubDescObj='descObj'></desc-view>
    </div>
</template>

<template id="desc-view">
    <div>
      <h1>{{pushsubdescobj.title}}</h1>
      <p :style="{fontSize: fontSize + 'px'}">{{pushsubdescobj.desc}}</p>
    </div>
</template>

<script>
    Vue.component('desc-view', {
        template: "#desc-view",
        props: {
            pushsubdescobj: {
                type: Object,
                default: function () {
                    return { 
                        title: '这是一个默认的标题',
                        desc: '这是一个默认的内容'
                    }
                }
            }
        },
        data: function () {
            return {
                fontSize : 12
            }
        },
        created () {
            var $this = this;
            // 接收事件,当前实例vm接收自定义事件
            this.$root.$on('btn-click', function (size) {
                $this.fontSize += size;
                // 接收到的数据
                console.log('btn-click', 1)
            });
        }
    });

    Vue.component('main-view', {
        template: '#main-view',
        data: function () {
            return {
                descObj: {
                    title: 'Android',
                    desc: '这是Android的描述信息'
                }
            }
        },
        methods: {
            onChangeDescClick: function (type) {
                this.descObj.title = type;
                this.descObj.desc = '这是' + type + '的描述信息';
            },
            
            // btn-click自定义事件的名称
            onDescFontSizeClick: function () {
                this.$root.$emit('btn-click', 1);
            }
        },
        created() {
        },
    });

    var vm = new Vue({
        el: '#app'
    });
</script>

首先在 desc-view 中通过 this.$root 来获取当前的 vm(app) 实例,接收了一个 btn-click 自定义事件,该事件被调用的时候会改变 data 中的 fontSize 的值,使其自增 size

然后在 main-view 中新增一个 onDescFontSizeClick方法,当用户调用onDescFontSizeClick方法的时候,会通过 this.$root.$emit('btn-click', 1); 来激活 btn-click 事件,并传入了一个参数,匹配 size1

也就是说当点击 DescFontSize++按钮的时候,desc-view中的 <p> 标签展示的文字大小会自增 1

感谢您的阅读,如果对您有帮助,欢迎关注"CRMEB"。码云上有我们开源的商城项目知识付费项目JAVA版全开源商城系统,学习研究欢迎使用,老铁顺手点个star呗,老板奖励五毛,分你两毛五,😂😂关注我们保持联系!

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐