Appearance
组件自定义事件 (component-custom-events)
事件名
事件名 可以 与 组件名 和 属性名(prop) 一样,自动进行大小写转换
js
this.$emit('yourEvent');
html
<your-component @your-event="doSth" />
DOM 模板中 建议使用 kebab-case 形式,字符串模板则没有这个限制
定义自定义事件
js
app.component('your-custom-component', {
emits: ['sth-happen', 'click']
});
正如看到的那样,如果 emits 中定义了原生事件,则会使用组件中相应的事件侦听器
验证抛出的事件
触发事件后通过自定义代码进行校验以决定该事件是否有效,类似组件的属性(prop)校验。
js
app.component('your-custom-component', {
emits: {
// 无验证
click: null,
// 验证事件
'sth-happen': ({ when, where, who, how }) => {
if ([when, where, who].filter(Boolean).length < 3) {
console.warn(`sth-happen: invalidate event`);
return false;
}
return true;
}
},
methods: {
report() {
this.$emit('sth-happen', { when: Date.now(), where: null })
}
}
});
v-model 参数
之前 v-model 只是 对 value|checked 等 单个特定属性 封装的语法糖,
"默认情况下,组件上的 v-model 使用 modelValue 作为 prop 和 update:modelValue 作为事件。我们可以通过向 v-model 传递参数来修改这些名称:"
html
<your-form v-model:label="xxx" />
对应的组件代码可以是:
js
app.component('your-form', {
props: {
label: String
},
emits: ['update:label'],
template: `
<input
type="text"
:value="label"
@input="$emit('update:label', $event.target.value)">
`
})
多个 v-model 绑定
<YourForm4Models v-model:label="x" v-model:value="y" />
title:
value:
在当前组件定义好相应组件属性数据 在子组件中只要触发相应 update:xxx
事件即可修改上级组件的属性数据
@/pages/40-lrn/20-vue3/40-component-custom-events/components/YourForm4Models.vue
vue
<template>
<div>
<div>
title:
<input :value="label" @input="emit('update:label', $event.target['value'])">
{{label}}
</div>
<div>
value:
<input :value="value" @input="emit('update:value', $event.target['value'])">
{{value}}
</div>
</div>
</template>
<script lang="ts" setup>
import { defineProps, toRefs, defineEmits } from "vue"
const props = defineProps<{
label: string;
value: string;
}>();
const { label, value } = toRefs(props);
let emit = defineEmits(['update:label', 'update:value']);
</script>
处理 v-model 修饰符
2.x 中的 表单输入绑定 v-model 的 .trim、.number、.lazy 等修饰符都是框架内部实现的。
3.x 中,可以自定义修饰符
下面创建一个自定义修饰符 reverse 作用是返回字符顺序相反的字符串
@/pages/40-lrn/20-vue3/40-component-custom-events/components/ReverseModifierExample.vue
vue
<template>
<input :value="modelValue" @input="onInput" />
</template>
<script lang="ts" setup>
import { defineProps, defineEmits } from "vue"
const props = withDefaults(defineProps<{
modelValue: string;
modelModifiers: Record<string, boolean>;
}>(), {
modelModifiers: () => ({}),
});
const emit = defineEmits(['update:modelValue']);
const onInput = ($event) => {
let val = $event.target['value'];
let result = props.modelModifiers.reverse
? Array.from(val).reverse().join('')
: val;
emit('update:modelValue', result);
};
</script>