Search code examples
vue.jsvuejs2vuejs3vue-component

Using Emits in Vue 3


I am going to upgrade vue 2 project to vue 3. There are two emits in my vue 2 project. I want to change it as vue 3. I found a way to use emits in vue 3 by using typescript. Here is the script part of code in my upgraded project.

<script lang="ts">
import { Component, Vue } from 'vue-facing-decorator';
import { DataTableActionTypes } from '@/shared/enums/dataTableActionTypes.enum';
import Modal from '@/shared/components/modal/Modal.vue';
import { defineComponent } from 'vue';

export default defineComponent ({
    name : 'AddressListActionButtons',
    components: {
        Modal
    },
    props: {
        item : {
            type : undefined,  //since type as any in vue 2 project
        },
        
    },
    showDeleteAddressConfirmation = false,

    methods : {
        onDeleteAddressClick() {
            this.showDeleteAddressConfirmation = true;
            this.onAction(this.item, DataTableActionTypes.ActionButtonSelect);
        },

        onCloseDelete() {
            this.showDeleteAddressConfirmation = false;
            this.onAction(this.item, DataTableActionTypes.ResetActionButtton);
        },
        deleteAddress() {
            this.showDeleteAddressConfirmation = false;
            this.onDeleteAddress(this.item, DataTableActionTypes.Delete)
        }
    },
    

    emits : ['customEvent'],
        setup(props, { emit }) {
            const onAction = (data: any, type: DataTableActionTypes)=>{
            
            }
        },
        
    emits : ['customEvent'],
        setup(props, { emit }) {
            const onDeleteAddress = (id: number, type: DataTableActionTypes)=>{
            
            }
        },    


})
</script>

Since there are two emits, there is an error message called An object literal cannot have multiple properties with the same name.ts(1117). Actually this error occurs since I use two emits keywords. Is there is an solution to solve this error?


Solution

  • I would recommend using the composition api like this:

    <script setup>
    import { defineEmits } from "vue";
    const emit = defineEmits(["emit1", "emit2"]);
    
    const sendEmit1 = () => {
      emit("emit1");
    };
    const sendEmit2 = () => {
      emit("emit2");
    };
    </script>
    
    <template>
      <button @click="sendEmit1">emit 1</button>
      <button @click="sendEmit2">emit 2</button>
    </template>
    
    <script>
    export default {
      name: "HelloWorld",
    };
    </script>
    

    Working example on codesandbox