美文网首页
Vue父子组件的通信

Vue父子组件的通信

作者: 名字是乱打的 | 来源:发表于2020-05-26 01:26 被阅读0次
    父子组件通信方式

    一 父组件向子组件通过props传递数据

    在组件中,使用选项props来声明需要从父级接收到的数据。
    props的值有两种方式:
    方式一:字符串数组,数组中的字符串就是传递时的名称。
    方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。

    Prop 是你可以在组件上注册的一些自定义 attribute
    当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。

    1. props值为数组时候

    为了给博文组件传递一个标题,我们可以用一个 props 选项将其包含在该组件可接受的 prop列表中:

    Vue.component('blog-post', {
      props: ['title'],
      template: '<h3>{{ title }}</h3>'
    })
    

    一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问data中的值一样。

    一个 prop 被注册之后,你就可以像这样把数据作为一个自定义 attribute 传递进来,在这里我们直接用k-v对显示了值,而没有进行v-bind的动态绑定(下面有介绍):

    <blog-post title="My journey with Vue"></blog-post>
    <blog-post title="Blogging with Vue"></blog-post>
    <blog-post title="Why Vue is so fun"></blog-post>
    

    然而在一个典型的应用中,你可能在 data 里有一个博文的数组:

    new Vue({
      el: '#blog-post-demo',
      data: {
        posts: [
          { id: 1, title: 'My journey with Vue' },
          { id: 2, title: 'Blogging with Vue' },
          { id: 3, title: 'Why Vue is so fun' }
        ]
      }
    })
    

    并想要为每篇博文渲染一个组件:

    <blog-post
      v-for="post in posts"
      v-bind:key="post.id"
      v-bind:title="post.title"
    ></blog-post>
    

    如上所示,你会发现我们可以使用 v-bind 来动态传递 prop。这在我们一开始不清楚要渲染的具体内容,比如从一个 API 获取博文列表的时候,是非常有用的。


    2. props值为对象时候

    通常我们希望每个 prop 都有指定的值类型。这时,我们可以以对象形式列出 prop,这些 property 的名称和值分别是 prop 各自的名称和类型

    props: {
      title: String,
      likes: Number,
      isPublished: Boolean,
      commentIds: Array,
      author: Object,
      callback: Function,
      contactsPromise: Promise // or any other constructor
    }
    

    3. 关于props值为对象时候,我们可以对传入的数据做校验或者说验证

    我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。

    3.1.在props中我们可以传一个值做一个对象元素传入,对其做三个限定.如下如代码中的name
    • type 约定该元素类型
    • default 约定默认值(如果父组件不传入值的话将直接使用默认值)
    • required 约定是否要求必须传入(如果要求了父组件没有传入则会报错)
    props: {
        title:String,
           propB: [String, Number],
        name:{
                type:String,
                default:"zyh",
                required:true
                }
            }
    
    3.2 我们可以对传入的值约定多个可能类型

    propB: [String, Number]

    3.如果我们要求传入的数据为对象或者数组,那么默认值需要用工厂函数获取

     // 带有默认值的对象
      propE: {
          type: Object,
          // 对象或数组默认值必须从一个工厂函数获取
          default: function () {
            return { message: 'hello' }
          }
        }
    

    二 子传父---通过监听子组件事件传递数据和信号给父组件

    不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。
    举个例子,如果触发一个 camelCase 名字为的事件:this.$emit('myEvent')
    则监听这个名字的 kebab-case 版本是不会有任何效果的:
    <my-component v-on:my-event="doSomething"></my-component>
    不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。

    并且v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent将会变成 v-on:myevent——导致 myEvent不可能被监听到。

    因此,Vue官方推荐始终使用 kebab-case 的\color{red}{事件名}

    自定义事件的流程:
    • 在子组件中,通过$emit来触发事件。
    • 在父组件中,通过v-on来监听子组件事件。 一个传递加减信号的demo

    自定义组件的 v-model

    一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的model 选项可以用来避免这样的冲突:

    Vue.component('base-checkbox', {
      model: {
        prop: 'checked',
        event: 'change'
      },
      props: {
        checked: Boolean
      },
      template: `
        <input
          type="checkbox"
          v-bind:checked="checked"
          v-on:change="$emit('change', $event.target.checked)"
        >
      `
    })
    

    现在在这个组件上使用 v-model 的时候:

    <base-checkbox v-model="lovingVue"></base-checkbox>
    这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 <base-checkbox>触发一个 change事件并附带一个新的值的时候,这个 lovingVue 的 property 将会被更新。

    注意你仍然需要在组件的 props 选项里声明 checked 这个 prop。


    关于子组件向父组件传参数量问题

    $emit传递一个参数时

    子组件:
    this.$emit('closeChange',false);
    
    
    父组件:
    <posilCom @closeChange="closeCom($event)"></posilCom>
    closeCom(msg) {
        this.msg = msg;
    }
    

    $emit传递多个参数时

    子组件:
    this.$emit('closeChange',false,true);
    
    父组件:
    <posilCom @closeChange="closeCom(arguments)"></posilCom>
    closeCom(msg) {
        this.msg1 = msg[0];
        this.msg2 = msg[1];
    }
    

    相关文章

      网友评论

          本文标题:Vue父子组件的通信

          本文链接:https://www.haomeiwen.com/subject/dizyahtx.html