vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue3组件事件和defineEmits

vue3中组件事件和defineEmits示例代码

作者:ps酷教程

这篇文章主要给大家介绍了关于vue3中组件事件和defineEmits的相关资料,组件事件是Vue组件之间进行通信的一种方式,文中通过代码示例介绍的非常详细,需要的朋友可以参考下

1. 事件基础

示例

Blog.vue

<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 './BlogPost.vue'
export default {
    name: 'Blog',
    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>
<style lang="scss"></style>

BlogPost.vue

<template>
    <div class="blog-post">
        <h4>{{ title }}</h4>
        <button @click="$emit('enlarge-text')">Enlarge text</button>
    </div>
</template>
<script>
export default {
    name: 'BlogPost',
    props: ['title'],
    // 这个emits声明选项不是必须的
    emits: ['enlarge-text']
}
</script>
<style lang="scss"></style>

2. 触发与监听事件

2.1 触发事件

在组件的模板表达式中,可以直接使用 $emit 方法触发自定义事件

$emit() 方法在组件实例上也同样以 this.$emit() 的形式可用:

<templte>
	<button @click="$emit('someEvent')">click me</button>
</template>
<script>
	export default {
	  methods: {
	    submit() {
	      this.$emit('someEvent')
	    }
	  }
	}
</script>

2.2 监听事件

<MyComponent @some-event="callback" />
<MyComponent @some-event.once="callback" />

3. 事件参数

3.1 示例1

Blog.vue

<template>
    {{ count }}
    <BlogPost @increase-by="(n) => count += n" />
    <BlogPost @increase-by="increaseCount" />
</template>
<script >
import BlogPost from './BlogPost.vue'
export default {
    name: 'Blog',
    components: {
        BlogPost
    },
    data() {
        return {
            count: 0
        }
    },
    methods: {
        increaseCount(n,m,e) {
            console.log(n,m,e); // 1, 2, PointerEvent {isTrusted: true, _vts: 1682821628803, pointerId: 1, width: 1, height: 1, …}
            this.count += n
        }
    }
}
</script>
<style lang="scss"></style>

BlogPost.vue

<template>
    <div class="blog-post">
        <button @click="$emit('increaseBy', 1, 2, $event)">
            Increase by 1
        </button>
    </div>
</template>
<script>
export default {
    name: 'BlogPost',
}
</script>
<style lang="scss"></style>

3.2 示例2(defineEmits)

子组件可以触发自定义事件,父组件使用该子组件时,可以监听该组件的事件,并为监听的事件绑定事件处理函数, 当该子组件触发了该事件时,父组件对应的事件处理函数就会执行。

MyComponent.vue

<template>
    <!-- 在组件的模板表达式中,可以直接使用 $emit 方法触发自定义事件 -->
    <!-- 可以通过 v-on (缩写为 @) 来监听事件, 即:@click -->
    <!-- 这里可以使用驼峰命名形式触发的事件名称, 而在父组件中使用短横线命名形式监听 -->
    <!-- 传入3个参数, 则在父组件中监听函数中, 也应至少有3个参数, 
         否则按参数个数赋值,也可以在这里传个对象过去,就只需要一个参数了,
         并且可以使用$event, 将当前事件传过去 -->
    <!-- 参数也可以使用模板中拿到的参数, 比如v-for循环里拿到的每一项数据 -->
    <button v-on:click="$emit('doUpdate',$event,1,2)">触发doUpdate事件</button> <br/>
    <button v-on:click="$emit('refresh', {name:'zzhua',age:Math.floor(Math.random() * 20)})">触发refresh事件</button>
    子组件中person: {{ person }}<br/>
    <!-- 可以使用事件修饰符, once表示该事件只会触发1次 -->
    <button v-on:click.once="handleClick()">触发click事件</button>
</template>
<script lang="ts" setup>
    import { ref,reactive,onUpdated } from 'vue'
    /* 1. defineEmits() 宏不能在子函数中使用。它必须直接放置在 <script setup> 的顶级作用域下 */
    /* 2. 显式地使用了 setup 函数而不是 <script setup>,则事件需要通过 emits 选项来定义,emit 函数也被暴露在 setup() 的上下文对象上 */
    const emit = defineEmits(['doUpdate']) /* 可以不需要定义doUpdate, 但建议定义doUpdate, 以此来声明此组件可以被触发的事件 */
     function handleClick () {
        console.log('click');
        emit('doUpdate',e,3,4) /* 使用emit,手动触发doUpdate事件 */
    }
    const props = defineProps(['person'])
    onUpdated(()=>{
        console.log('---组件渲染更新了---') /* 当通过触发子组件事件, 父组件监听到该组件的该事件, 修改了person的ref值, 从而组件会更新 */
    })
</script>
<style lang="scss">
    button {
        margin: 5px;
    }
</style>

Test.vue

<template>
    <!-- 可以使用短横线形式监听当前这个组件的事件,并指定事件处理函数 -->
    <my-component :person="person" v-on:do-update="handleUpdate" @refresh="handleRefresh" ></my-component><br/>
    父组件中person: {{ person }}
</template>
<script lang="ts" setup>
    import { ref,reactive,computed } from 'vue'
    import MyComponent from './MyComponent.vue';
    const person = ref({ name: 'demoName', age: NaN})
    function handleUpdate(event,payload1,payload2) {
        console.log(event); // PointerEvent {isTrusted: true, _vts: 1678062697219, pointerId: 1, width: 1, height: 1, …}
        console.log(payload1, payload2);
    }
    function handleRefresh( p) {
        console.log(p); // {name: 'zzhua', age: 18}
        person.value = p
    }
</script>
<style lang="scss">
</style>

4. 声明触发的事件

5. 事件校验

示例1

Blog.vue

<template>
    {{ count }}
    <BlogPost @submit="handleSubmit" />
</template>
<script >
import BlogPost from './BlogPost.vue'
export default {
    name: 'Blog',
    components: {
        BlogPost
    },
    data() {
        return {
            count: 0
        }
    },
    handleSubmit(payload) {
        console.log(payload);
    }
}
</script>
<style lang="scss"></style>

BlogPost.vue

<template>
    <div class="blog-post">
        <button @click="$emit('submit', {password:'123456'})">
            submit
        </button>
    </div>
</template>
<script>
export default {
    name: 'BlogPost',
    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>
<style lang="scss"></style>

示例2(defineEmits)

MyComponent.vue

<template>
    <button @click="submitForm(123,456)">触发submitForm事件</button>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
const emit = defineEmits({
    // 没有校验
    click: null,
    // 校验 submit 事件
    submit: ({ email, password }) => {
        if (email && password) {
            console.log(email, password);
            return true
        } else {
            console.warn('Invalid submit event payload!')
            return false
        }
    }
})
function submitForm(email, password) {
    emit('submit', { email, password })
}
</script>
<style lang="scss">
button {
    margin: 5px;
}
</style>

Test.vue

<template>
    <MyComponent></MyComponent>
</template>
<script lang="ts" setup>
    import { ref,reactive,computed } from 'vue'
    import MyComponent from './MyComponent.vue';
</script>
<style lang="scss">
</style>

总结 

到此这篇关于vue3中组件事件和defineEmits的文章就介绍到这了,更多相关vue3组件事件和defineEmits内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文