Vue.Js - How to Call Method from Another Component

vue.js - call component method from another component

yes it is possible. Step 3 will do what you explicitly asked but there are better ways.

Three ways.

1) VUEX: Move the method you wish to call, to Vuex and any associated reactive data properties to the store. And use getters to retrieve the updated data.

2) MIXINS: With mixins you would move your component2.vue and associated data properties to a mixin, and import it in both components, allowing it to be called from each.

3) Hacky fix that actually calls the method from another component (not best practice)

You can mount methods to $root and call them from another component, by emiting a event. Using your example it would look like the following.

Components2.vue // mount the method you wish to call


// new code
mounted() {

this.$root.$on("getProjects", () => {

return this.getProjects(url = '/api/departments');
});
}


Component1.vue // call the mounted method

 methods: {
// new code
emitGetProjects() {
this.$root.$emit("getProjects") //like this
}
},


more info here How can I call method in other component on vue.js 2? in case i made any typos

Vue call method of another component

You can call a method of another component by using a ref.

    <v-card-actions>
<v-btn
color="primary"
dark
@click="openModal">
Open Dialog
</v-btn> <!-- open modal dialog of modal component? -->
<tenant-number-modal ref="modal"></tenant-number-modal>
</v-card-actions>
...
<script>
export default {
data () {
return {
//visible: true,
//dialog: false,
//uniqueTenantNumber: ''
}
},
methods: {
openModal() {
this.$refs.modal.showModal();
}
}
}
</script>

Your modal component:

<template>
<v-layout row justify-center>
...
<v-dialog
v-model="dialog"
max-width="290">
<v-card>
<v-card-title class="headline">test</v-card-title>
</v-card>
</v-dialog>
</v-layout>
</template>

<script>
export default {
data () {
return {
dialog: false
}
},
methods: {
showModal() {
this.dialog = true;
}
}
}
</script>

Vue.js : Call a Method from another Component

You could call emit on Component2 and call fetchData when Component1 receives it:

<component2 @fetch="fetchData()"></component2>

And on Component2, you need to emit fetch at somepoint. For example:

export default {
created() {
this.$emit('fetch')
}
}

Call a function from another component using composition API

One way to solve this is to use events for parent-to-child communication, combined with template refs, from which the child method can be directly called.

  1. In ComponentB.vue, emit an event (e.g., named continue-event) that the parent can listen to. We use a button-click to trigger the event for this example:
<!-- ComponentB.vue -->
<script>
export default {
emits: ['continue-event'],
}
</script>

<template>
<h2>Component B</h2>
<button @click="$emit('continue-event', 'hi')">Trigger continue event</button>
</template>

  1. In the parent, use a template ref on ComponentA.vue to get a reference to it in JavaScript, and create a function (e.g., named myCompContinue) to call the child component's continueFn directly.
<!-- Parent.vue -->
<script>
import { ref } from 'vue'

export default {

setup() {
const myComp = ref()
const myCompContinue = () => myComp.value.continueFn('hello from B')

return {
myComp,
myCompContinue,
}
},
}
</script>

<template>
<ComponentA ref="myComp" />

</template>

  1. To link the two components in the parent, use the v-on directive (or @ shorthand) to set myCompContinue as the event handler for ComponentB.vue's continue-event, emitted in step 1:
<template>

<ComponentB @continue-event="myCompContinue" />
</template>

demo

Note: Components written with the Options API (as you are using in the question) by default have their methods and props exposed via template refs, but this is not true for components written with <script setup>. In that case, defineExpose would be needed to expose the desired methods.

Call a method of another component

In order to use emit one of the components need to call the other (parent and child). Then you emit from the child component to the parent component. For example if Dashboard component uses the Modal component you can emit from the Modal to the Dashboad.

If your components are separate from one another you can make use of Mixins. You can create a mixin UsersMixin.js like the following:

export default {
methods: {
getUsers: function () {
// Put your code here for a common method
}
}
}

Then import the mixin in both your components, and you will be able to use its methods:

Modal.vue

<script>
import UsersMixin from './UsersMixin';
export default {
name: 'modal'
mixins: [
UsersMixin
],
created: function () {
this.getUsers();
}
}
</script>

Dashboard.vue

<script>
import UsersMixin from './UsersMixin';
export default {
name: 'dashboard',
mixins: [
UsersMixin
],
methods: {
add_adddress () {
this.getUsers(); // I would like to access here like this
//some code here
}
},
}
</script>

Call method from another component in Vue.js

You can use a service as a go-between. Usually, services are used to share data but in javascript functions can be treated like data also.

The service code is trivial, just add a stub for the function changeName

changeName.service.js

export default {
changeName: function () {}
}

To have services injected into the components, you need to include vue-injector in the project.

npm install --save vue-inject
or
yarn add vue-inject

and have a register of services,

injector-register.js

import injector from 'vue-inject';

import ChangeNameService from '@/services/changeName.service'

injector.service('changeNameService', function () {
return ChangeNameService
});

then in main.js (or main file may be called index.js), a section to initialize the injector.

import injector from 'vue-inject';
require('@/services/injector-register');
Vue.use(injector);

Finally, add the service to the component dependencies array, and use the service

compname.vue

<script>
export default {
dependencies : ['changeNameService'],
created() {
// Set the service stub function to point to this one
this.changeNameService.changeName = this.changeName;
},
...

compbutton.vue

<script>
export default {
dependencies : ['changeNameService'],
name: 'compbutton',
methods: {
buttonClicked: function () {
this.changeNameService.changeName();
}
}
...

Add a # to the button href to stop page reloads

<a href="#" v-on:click="buttonClicked">Change Name</a>

See the whole thing in CodeSandbox

How can I call method in other component on vue.js 2?

If these 2 components are siblings (no parent & child), then one solution is to use event bus.

General idea is to build a global event handler like so:
in main.js

window.Event = new Vue();

Then in your first component fire an event:

....
.then((response) => {
Event.$emit('createImage', item, response)
});

and in second component register a handler for listening to createImage event in mounted() hook:

...
mounted() {
Event.$on('createImage', (item, response) => {
// your code goes here
}
}

You can find more info by reading this turtorial and watching this screen cast.

Call a Vue.js component method from outside the component

In the end I opted for using Vue's ref directive. This allows a component to be referenced from the parent for direct access.

E.g.

Have a compenent registered on my parent instance:

var vm = new Vue({
el: '#app',
components: { 'my-component': myComponent }
});

Render the component in template/html with a reference:

<my-component ref="foo"></my-component>

Now, elsewhere I can access the component externally

<script>
vm.$refs.foo.doSomething(); //assuming my component has a doSomething() method
</script>

See this fiddle for an example: https://jsfiddle.net/xmqgnbu3/1/

(old example using Vue 1: https://jsfiddle.net/6v7y6msr/)

Edit for Vue3 - Composition API

The child-component has to return the function in setup you want to use in the parent-component otherwise the function is not available to the parent.

Note: <sript setup> doc is not affacted, because it provides all the functions and variables to the template by default.



Related Topics



Leave a reply



Submit