• 组件事件:用于子组件向父组件传递数据。

触发与监听事件

  1. https://cn.vuejs.org/guide/components/events.html#emitting-and-listening-to-events
  2. 组件的事件监听器也支持.once修饰符:(执行一次)
1
<MyComponent @some-event.once="callback" />
  1. 父组件 App.vue
 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
<template>
    <div>
        <MyComponent @some-event="callback" />
        Number is: <div>{{ number }}</div>

        <hr />

        <!-- .once 触发一次 -->
        <MyComponent @some-event.once="callback2" />
        Number is: <div>{{ number2 }}</div>
    </div>
</template>

<script setup>
import {ref} from 'vue'
import MyComponent from './components/MyComponent.vue';

const number = ref(0)
function callback() {
    number.value += 1
}

const number2 = ref(0)
function callback2() {
    number2.value += 1
}
</script>
  1. 子组件 MyComponent.vue
1
2
3
4
5
6
7
<template>
    <button @click="$emit('someEvent')">Click Me</button>
</template>

<script setup>

</script>

事件参数

  1. https://cn.vuejs.org/guide/components/events.html#event-arguments
  2. 父组件 App.vue
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<template>
    <div>
        <MyComponent @increase-by="increaseCount" />
        Count is: {{ count }}
    </div>
</template>

<script setup>
import {ref} from 'vue'
import MyComponent from './components/MyComponent.vue';

const count = ref(0)
function increaseCount(n) {
    count.value += n
}
</script>
  1. 子组件 MyComponent.vue
1
2
3
4
5
6
7
8
9
<template>
    <!-- 如果想传递event最后一个参数传入 $event -->
    <button @click="$emit('increaseBy', 1)">
    Increase by 1
    </button>
</template>
<script setup>

</script>

声明触发的事件

  1. https://cn.vuejs.org/guide/components/events.html#declaring-emitted-events
  2. 通过defineEmits()宏来声明它要触发的事件,可以更加灵活的触发事件。
  3. 注意事项:defineEmits()宏不能在子函数中使用。如上所示,它必须直接放置在<script setup>的顶级作用域下。
  4. 父组件 App.vue
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<template>
    <div>
        <MyComponent @submit="submitForm" @in-focus="inFocus" />
    </div>
</template>

<script setup>
import MyComponent from './components/MyComponent.vue';

function submitForm() {
    console.log('submit')
}

function inFocus() {
    console.log('inFocus')
}
</script>
  1. 子组件 MyComponent.vue
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<template>
    <button @click="buttonClick">submit</button>
    <button @click="buttonClickInFocus">inFocus</button>
</template>

<script setup>
const emit = defineEmits(['inFocus', 'submit'])

function buttonClick() {
  emit('submit')
}

function buttonClickInFocus() {
  emit('inFocus')
}
</script>

事件校验

  1. https://cn.vuejs.org/guide/components/events.html#events-validation
  2. 父组件 App.vue
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<template>
  <div>
     <MyComponent @submit="submitForm" @click="inFocus" />
  </div>
</template>

<script setup>
import MyComponent from './components/MyComponent.vue';

// 传入的是一个json对象 {email: 'a', password: 'b'}
function submitForm(a) {
    console.log('submit', a)
}

function inFocus() {
    console.log('inFocus')
}
</script>
  1. 子组件 MyComponent.vue
 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
<template>
    <button @click="submitForm('a', 'b')">submit</button>
    <button @click="click">click</button>
</template>


<script setup>
const emit = defineEmits({
  // 没有校验
  click: null,

  // 校验 submit 事件
  submit: ({ email, password }) => {
    if (email && password) {
      return true
    } else {
      console.warn('Invalid submit event payload!')
      return false
    }
  }
})

function submitForm(email, password) {
  emit('submit', { email, password })
}

function click() {
    emit('click')
}
</script>