【青训营】深入事件

42 阅读1分钟

这是我参与「第四届青训营 」笔记创作活动的的第10天 

重点内容

  • 深入事件

详细内容

深入事件

前面已经介绍如何声明一个自定义事件以及传递参数,这次进一步详细介绍组件事件

事件的声明与校验

显示声明事件: emits:[事件1,事件2.....]

export default {
  emits: ['inFocus', 'submit']
}

事件校验:语法类似于props

语法结构:emits:{事件名:事件校验方法{}}

返回值: type:Boolean, value: true:通过校验|false:校验失败|null:没有校验

例如:

export default {
  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 })
    }
  }
}

配合v-model使用

如果在一个组件上使用v-model:

<CustomInput v-model="searchText" />

在运行过程中,v-model会被展开为以下形式:

<CustomInput
  :modelValue="searchText"
  @update:modelValue="newValue => searchText = newValue"
/>

如果要让这个组件成功运行,子组件内部需要:

  1. input.value attribute = modelValue props
  2. 当input中的值发生改变时,改变modelValue中的值

于是子组件中的代码可以写为:

<!-- CustomInput.vue -->
<script>
export default {
  props: ['modelValue'],
  emits: ['update:modelValue']
}
</script>

<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>

通过计算属性也可以实现类似效果:

<!-- CustomInput.vue -->
<script>
export default {
  props: ['modelValue'],
  emits: ['update:modelValue'],
  computed: {
    value: {
      get() {
        return this.modelValue
      },
      set(value) {
        this.$emit('update:modelValue', value)
      }
    }
  }
}
</script>

<template>
  <input v-model="value" />
</template>

v-model 在组件上都是使用 modelValue 作为 prop,并以 update:modelValue作为对应的事件。也可以通过给 v-model 指定一个参数来更改这些名字

透传 Attributes

如果某些属性没有声明为props或者emits中的属性,直接传递给子组件,透传的 attribute 会自动被添加到根元素上,最常见的例子就是 classstyle 和 id。除了常见的属性,还可以传递监听器。和单根节点组件有所不同,有着多个根节点的组件没有自动 attribute 透传行为。