What is the correct way to trigger an event specified as a string parameter in the emit() function?

My current goal is to pass the emit name as a string (for example, 'showComponent') from child to parent. I then want to trigger another emit in the emitAction(callbackName: string) function, and finally execute the showComponent() function.

I'm not seeing any errors or warnings, so where am I going wrong?

Parent component:

<script setup lang="ts">

const showLoginPopup: Ref<boolean> = ref(false);

function showComponent() {
  showLoginPopup.value = true;
}

const emit = defineEmits<{
  (event: string): void;
}>()


function emitAction(callbackName: string) {
  emit(callbackName);
}

</script>

<template>
<ActionVue @emitAction="emitAction" v-for="action in actions"
            :title="action.title"
            :description="action.description"
            :buttonTitle="action?.buttonTitle"
            :actionType="action.actionType" />
</template>

Child component:

<script setup lang="ts">
const props = defineProps<Action>();
const emit = defineEmits<{
  (event: 'emitAction', callbackName: string): void;
}>()

</script>

<template>
    <button @click="emit('emitAction', props.actionType)">
     {{  props.buttonTitle }}
    </button>
</template>

Answer №1

Triggering a second emit will only pass the event up to the grandparent component. It is recommended to directly execute the function based on the emit name instead.

child:

<button @click="emit('showComponent')"

parent:

<ActionVue @showComponent="showComponent()">

If you absolutely need to invoke a function using a string value, you can dynamically call the function stored in the current application instance:

Parent component:

<script setup lang="ts">
    import { getCurrentInstance } from 'vue'
    const app = getCurrentInstance()

    function emitAction(callbackName: string) {
          // if callbackName === 'showComponent', runs function showComponent()
          app.setupState[callbackName](); 
    }

    function showComponent() {
        showLoginPopup.value = true;
    }
}

Answer №2

When using emit in the template, it's important to write it as $emit(…). Take a look at my example on Codepen to see how I implement this when calling emit in child components.

<!-- This works fine -->
<button @click="$emit('foo', 'bar')">Click</button>
<!-- This won't work as "emit" is not recognized as a function for the component-->
<button @click="emit('foo', 'bar')">Click</button>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Correctly inputting the 'in' statement - Avoid using a primitive value on the right side of an 'in' statement

I am currently facing an issue with my React code where I am getting the error message: The right-hand side of an 'in' expression must not be a primitive.. I am unsure about how to resolve this problem effectively: // The goal is to allow nu ...

What is the best way to add the ".html" suffix to pages in nuxt.js?

Is it possible to add the ".html" extension to a page address? For instance, changing "test_page" to "test_page.html" ...

Innovative idea for a time management system based on timelines and scheduling

My latest project involves creating a scrollable scheduler, inspired by vis-timeline and built using Vue.js. One of the main challenges I'm facing is achieving smooth infinite scrolling in all directions (past and future). I must confess that I&apo ...

Navigating a text input field in a NextJS application

Having trouble with handling input from a textarea component in a NextJS app. This is the structure of the component: <textarea placeholder={pcHld} value={fldNm} onChange={onChangeVar} className="bg-cyan-300" ...

Removing duplicate values in Vue after sorting

Explore <div v-for="todo in sortedArray"> <b-button block pill variant="outline-info" id="fetchButtonGap" v-model:value="todo.items[0].arrivalTime"> {{fromMilTime(todo.items[0].arrivalTime)}} < ...

JavaScript has a feature called "functions" which allow the declaration of named blocks of

Currently, I am developing an Electron app in typescript. In my main.ts file, I have instantiated a custom CommunicationProvider class object. What I want is for this class to declare multiple methods (specified in an interface that it implements) but have ...

Implementing Undo and Redo functionality in Vuex by capturing and restoring state snapshots

Overview I have developed an undo-redo feature for a plugin, which follows the steps outlined below. Implemented Steps (General) Add the previous state snapshot on every action taken. Undo using a customized replaceState method with the previousState as ...

Learn how to manipulate CSS classes within a slot using Vue.js

Struggling to crack a simple logic puzzle, I desperately need your assistance. My aim is to add or modify the class name within a slot. // Parent component <div class="col"> <slider> <slide v-for="intro in compOpts.blockIntro"> ...

The tRPC setData hook is limited in its ability to access all data necessary for optimistic UI updates

As I integrate mutations using tRPC and React Query to optimistically update my UI upon adding a new item, I've encountered an issue. The problem lies in the query I'm updating, which requires specific properties like auto-generated IDs or datab ...

The error message "Uncaught ReferenceError: exports is not defined and require" indicates that

I am currently developing an app using angularjs and typescript, but I've encountered a persistent error that has me stumped. Below is the snippet of my code: export var NgApp = new application.Startup(); ///<reference path="../../../../../typin ...

Execute a VueJS API call every 20 minutes

I am retrieving data from an API endpoint to display information about coin names. I would like this information to update every 20 minutes, but for testing purposes, I have set it to refresh every 500 milliseconds. However, my current approach of fetching ...

Deploying Vue.js applications

I am working on a Vue application that was created using vue-cli. It is semi-developed and I would like to show the progress to a customer. Therefore, I am looking to deploy what we have so far. If I execute the script npm run build, will I still be able ...

Randomly selecting an element from an array as the default option in vue.js

I am working on a neat little tool to learn vue.js where users can find out the time it takes to travel from one location to another: Codepen It's functioning fairly well at the moment, but I want to include a random value from each array when the pa ...

After pressing the login button, my intention is to transition to a different page

I am relatively new to web development and working with angular. I have a login component that, upon hitting the LOGIN button, should redirect to another component on a different page. However, currently, when I click the button, it loads the data of the o ...

Having issues with Angular material autocomplete feature - not functioning as expected, and no error

I have set up my autocomplete feature, and there are no error messages. However, when I type something in the input field, nothing happens - it seems like there is no action being triggered, and nothing appears in the console. Here is the HTML code: ...

The Heart of the Publisher-Subscriber Design Paradigm

After reading various online articles on the Publisher-Subscriber pattern, I have found that many include unnecessary domain-specific components or unreliable information inconsistent with OOP standards. I am seeking the most basic and abstract explanatio ...

Tips for obtaining type narrowing for a function within a mixed array

In my coding adventure, I have crafted a brilliant match function. This function is designed to take a value along with an array of [case, func] pairs. The value is then compared to each case, and if a match is found, the associated func is executed with t ...

Error: The specified module is missing an export that was requested

Hello, I encountered an error in my console that reads: "Uncaught SyntaxError: The requested module './components/tileHeader/controller.js' does not provide an export named 'tileHeader'". Below is the code snippet causing the issue: co ...

Tips for dynamically updating the API path in VUEX state

Currently, I am working on dynamically updating the API path within my Vuex state. When the page loads, I have set a default path of "example.com/api/datasetA.json" in Vuex. However, I would like this path to be updated to "example.com/api/datasetB.json" b ...

Guide on properly specifying mapDispatchToProps in a component's props interface

In my project, I have a connected component utilizing mapStateToProps and mapDispatchToProps along with the connect HOC from react-redux. My goal is to create concise and future-proof type definitions for this component. When it comes to defining types fo ...