2-3-vue框架-组件-vue-component组件化开发-组件的事件(子传父)

背景

我们会发现有时候它需要与父组件进行交互。例如,将博客文章的文字能够放大,而页面的其余部分仍使用默认字号。

组件事件

这个事件不是用户点击行为的处理,那是用户事件,
这个组件事件是为了给组件之间传递数据的,老版本的vue也叫做自定义事件,现在叫组件事件
这两个区别你要搞清楚,

一,事件(不含参数)

定义一个包含事件的子组件

1,子组件可以通过调用内置的 $emit 方法,通过传入事件名称来抛出一个事件

2,可以通过 emits 选项来声明需要抛出的事件

这声明了一个组件可能触发的所有事件,还可以对事件的参数进行验证。

<!-- BlogPost.vue -->
<template>
  <div class="blog-post">
    <h4>{{ title }}</h4>
    <button @click="$emit('enlarge-text')">Enlarge text</button>
  </div>
</template>

<script>
export default {
    props: ['title'],
    emits: ['enlarge-text']
}
</script>

  • 1,这个子组件里面有一个按钮,点击按钮,可以放大子组件内容的字体,

使用一个含有事件的父组件

1,父组件可以通过 v-on 或 @ 来选择性地监听子组件上抛的事件,

因为有了 @enlarge-text="postFontSize += 0.1" 的监听,父组件会接收这一事件,从而更新 postFontSize 的值。
"postFontSize += 0.1"这个内容可以写到父组件的一个方法里面,是一样的,

<template>
<div :style="{ fontSize: postFontSize + 'em' }">
  <BlogPost
    v-for="post in posts"
    :key="post.id"
    :title="post.title"
    @enlarge-text="postFontSize += 0.1"
   />
</div>
</template>


<script>
  import BlogPost from "./components/demo1.vue"

  export default {
    components:{
      BlogPost
      },
    data() {
     return {
       posts: [
        { id: 1, title: 'My journey with Vue' },
        { id: 2, title: 'Blogging with Vue' },
        { id: 3, title: 'Why Vue is so fun' }
      ],
       postFontSize: 1
     }
    }

  }

</script>

二,事件(含参数)

定义一个含有事件参数的子组件

<!-- BlogPost.vue -->
<template>
  <div class="blog-post">
    <h4>{{ title }}</h4>
    <button @click="$emit('increaseBy', 1)">click me</button>
  </div>
</template>

<script>
export default {
    props: ['title'],
    emits: ['increaseBy']
}
</script>

使用一个含有事件参数的父组件

<template>
<div :style="{ fontSize: postFontSize + 'em' }">
  <BlogPost
    v-for="post in posts"
    :key="post.id"
    :title="post.title"
    @increase-by="increaseCount"
   />
</div>
</template>


<script>
  import BlogPost from "./components/demo1.vue"

  export default {
    components:{
      BlogPost
      },
    data() {
     return {
       posts: [
        { id: 1, title: 'My journey with Vue' },
        { id: 2, title: 'Blogging with Vue' },
        { id: 3, title: 'Why Vue is so fun' }
      ],
       postFontSize: 1
     }
    },
    methods :{
        increaseCount(n) {
            console.log(n)
            this.postFontSize += n
        }
      }

  }

</script>

三,事件校验

和对 props 添加类型校验的方式类似,所有触发的事件也可以使用对象形式来描述。
要为事件添加校验,那么事件可以被赋值为一个函数,接受的参数就是抛出事件时传入 this.$emit 的内容,返回一个布尔值来表明事件是否合法。
这是子组件往外抛出事件的之间,对抛出的事件进行校验,

<!-- BlogPost.vue -->
<template>
  <div class="blog-post">
    <h4>{{ title }}</h4>
    <button @click="$emit('submit', {'email':'222','password':'3333'})">click me</button>
  </div>
</template>

<script>
export default {
    props: ['title'],
    emits: {
        // 没有校验
        click: null,

        // 校验 submit 事件
        submit: ({ email, password }) => {
          if (email && password) {
            return true
          } else {
            console.warn('Invalid submit event payload!')
            return false
              }
            }
      },
    methods: {
        submitForm(email, password) {
          this.$emit('submit', { email, password })
        }
    }
}
</script>
posted @ 2021-09-14 05:21  技术改变命运Andy  阅读(53)  评论(0编辑  收藏  举报