Is there a more efficient method for invoking `emit` in Vue's Composition API from an external file?

Is there a more efficient way to access the emit function in a separate logic file?

This is my current approach that is functioning well:

foo.js

export default (emit) => {
    const foo = () => { emit('bar') };
    return { foo };
}

When consuming the component:

import { defineComponent } from '@vue/composition-api';
import foo from './foo';

export default defineComponent({
  setup(props, { emit }) {
    const { foo } = foo(emit);
    return { foo };
  }
});

I'm curious if there might be a more suitable method for achieving this. Is it considered bad practice to use emit within a consumable file?

Answer №1

If you have already found the solution, that's great! But if you want to try a similar approach as asked in the original question, there is an option called getCurrentInstance which has an emitter (the Vue 2 plugin for Composition API also has one).

import { getCurrentInstance } from 'vue';

export default () => {
  const { emit } = getCurrentInstance();

  const foo = () => {
    emit('bar');
  };

  return { foo };
}

Just keep in mind that this method will only work when calling functions/components that have the SetupContext.

Edit

The above solution is tailored for Vue 3, but with older versions of Vue + the Composition API plugin, there is a slight difference: Just like other Instance Properties, you need to prefix it with $ to use $emit. (The following example assumes Typescript as the target language, mentioned in the comment).

import { getCurrentInstance } from '@vue/composition-api';

export default () => {
  const { $emit, ...context } = getCurrentInstance() as NonNullable<ReturnType<typeof getCurrentInstance>>;

  const foo = () => {
    $emit.call(context, 'bar');
  };

  return { foo };
}

For Vue 3's Composition API, they have the ComponentInternalInstance interface exported.

P.S. It might be better to stick to assigning the instance to a variable and using context.$emit or vm.$emit instead of explicitly specifying a context for everything. This idea was initially generated without realizing that those Instance Properties are mainly for internal uses, which may not apply to the next Composition API.

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

Incorporate an image into your webpage with the Fetch API by specifying the image link - JavaScript

I've been attempting to retrieve an image using the imageLink provided by the backend server. fetchImage(imageLink) { let result; const url = `https://company.com/internal/document/download?ID=${imageLink}`; const proxyurl = 'https:/ ...

Encountering an error when attempting to access undefined property while using a method as a callback

Exploring OOP and angular is new to me. I am currently trying to implement a reusable table with pagination that triggers an API request when the page changes (pagination within the table component). The issue arises when I attempt to access my method usi ...

Concealing a div based on a condition

Having difficulty concealing a div once a specific condition is met. The condition depends on the user logging into a web application. In my CSS file, I have set the multipleBox div to visibility: hidden, along with other styling attributes like border co ...

Populate the dropdown menu with data from a JSON file

Recently, I created a custom JSON file and wanted to populate a select>option using this data. However, I encountered an error message saying: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///C:/.../p ...

The hyperlink functionality is disabled because Javascript is set to return false

JS Fiddle Example When using the 'FOO' and 'BOO' items in the navigation bar to open dropdown boxes, I have implemented a code that closes them when a click event occurs outside. This code has been working fine as shown below: $(docum ...

There seems to be an issue with my React application that was built using Webpack 5 and compiled with TypeScript. The @tailwind directive is not functioning properly in the browser, and

As I embark on creating a fresh react application using Webpack 5, Tailwind CSS, and Typescript, I find myself at a crossroads. Despite piecing together various tutorials, I am struggling to configure the postcss-loader for Tailwind. While traditional .css ...

Vue.js is unable to dispatch an event to the $root element

I'm having trouble sending an event to the root component. I want to emit the event when the user presses enter, and have the root component receive it and execute a function that will add the message to an array. JavaScript: Vue.component('inp ...

Issue with cordova plugin network interface connectivity

I'm currently working with Ionic 2 Recently downloaded the plugin from https://github.com/salbahra/cordova-plugin-networkinterface Attempting to retrieve IP addresses without utilizing global variables or calling other functions within the function ...

Adding the Authorization header in an Ajax request within ExtJS can be easily done by including the

I've been struggling to upload a file using ExtJS and web API. The issue I'm facing is that when trying to send an authorization header to the server, it always returns as null. I even attempted to include the header in the XHR request within the ...

Is it possible to pass the chart type as a property when using vue-chart.js?

Is it possible to pass the chart type as a property with vue-chart.js? I would love to see some example source code. Can you please provide guidance on this? ...

Exploring Angular controllers, promises, and testing

Currently, I am in the process of writing some unit tests for my controller that utilizes promises. The code snippet in question is as follows: UserService.getUser($routeParams.contactId).then(function (data) { $scope.$apply(function () { $sco ...

make changes to the current selection in the drop-down menu

Imagine I have a select list with 3 options: <select> <option>1</option> <option>2</option> <option>3</option> </select> My goal is to create a textfield and button that will allow me to upd ...

Implementing a click event listener on an iframe that has been dynamically generated within another iframe

Below is the code I used to attach a click event to an iframe: $("#myframe").load(function() { $(this.contentWindow.document).on('click', function() { alert("It's working properly"); }); }) Everything seems to be working co ...

Using the @ Symbol in Javascript ES6 Module Imports

One of the folders in my node_modules directory is called @mymodule, and within it, there is another folder named 'insidefolder'. The path to this folder looks like this: node_modules/@mymodule/insidefolder When trying to import insidefolder us ...

Compiler error occurs when trying to pass props through a higher-order component via injection

Recently, I have been experimenting with injecting props into a component using a higher order component (HOC). While following this insightful article, I came up with the following HOC: // WithWindowSize.tsx import React, {useEffect, useMemo, useState} fr ...

Encountered a login issue when attempting to access the localStorage

Any suggestions on resolving this error? Encountering a QuotaExceededError with DOM Exception 22 This issue arises when attempting to access the localStorage and assign data to the header. Currently working with Angular 2 on the client side using Type ...

What is the best approach for making a drawer resizable?

I am interested in making the material ui drawer resizable width using a draggable handle. Currently, I have implemented a solution that involves adding a mouse event listener to the entire application and updating the width based on the position of the ...

Error: The function screams cannot be accessed in this.state in React JS when using Firebase

This is the code I am working on and I need help to solve a problem: import React, { Component } from 'react' import Grid from '@material-ui/core/Grid'; import axios from 'axios'; class home extends Component { state = { ...

Scrolling back to the top of the page using Jquery instead of a specific div

Check out the code for my project here. The isotope feature is functioning correctly, however, when clicking on the image, instead of scrolling to the navigation under the red box as intended, the page scrolls all the way to the top. If I modify the follo ...

AngularJS offers a single checkbox that allows users to select or

For my code, I need to implement a single checkbox. In my doc.ejs file: <tr ng-repeat="folder_l in folderlist | orderBy:created_date" > <td> <div class="permit"> <input class="chkbtn move_check" type="checkbox" id=" ...