Vue communcation between child to parent to another child - javascript

I got a <payment-child-component> which handles all the subscriptions and payments, i also have
another <check-active-child-component>
I want these two components to communicate. persay in the <payment-component> a user cancel's his subscription i want to fire a method i have in <check-active-component> which called checkActive()
So from payment-component emits to parent-component when the subscription cancel method is triggered and then fires the checkActive() method inside check-active-component
So if my logic is good, the exact question is: how do i fire a method from parent to child component?

To call a method of a child component from its parent, you can use ref. Here is an example:
Child Component:
export default {
name: "ChildComponent",
methods: {
childMethod(){
console.log("hello from child");
}
}
};
Parent Component:
<template>
<div id="app">
<ChildComponent ref="myChild"/>
</div>
</template>
<script>
import ChildComponent from "./components/ChildComponent";
export default {
name: "App",
components: {
ChildComponent
},
mounted(){
this.$refs.myChild.childMethod()
}
};
</script>

This one is what I am using on my app.
Parent.vue
<template>
<a #click="run">Click me to execute method from child</a>
</template>
<script>
export default {
name:"parent",
methods: {
run() {
this.$root.$refs.child.methodtoexecute();
}
}
}
</script>
Child.vue
<script>
export default {
name:"child",
created() {
this.$root.$refs.child = this;
},
methods: {
methodtoexecute() {
alert("hello from child");
}
}
}
</script>

Related

Vue js pass a function from child chile to another child component on a click event

I am trying to pass a function when a button is clicked, the button is clicked in a child element, then passed through a parent element to another child component, and i dont want to use the store for that, How can i do that?
components/footer/footer.vue
-- This is where the button is clicked
<template>
<div class="footer-bottom-header-menu-bar mob" #click="showMenu">
<img src="~/assets/svg/menubar.svg" alt="+" />
</div>
</template>
<script>
export default {
methods: {
showMenu() {
this.$emit("show-menu");
}
}
}
</script>
layouts/default.vue
--This is the parent component where that receives the click function and is to pass it into the app-header
<template>
<div>
<app-header />
<Nuxt />
<app-footer #show-menu="showMenu()"/>
</div>
</template>
<script>
import header from "~/components/header/header";
import footer from "~/components/footer/footer";
export default {
components: {
'app-header': header,
'app-footer': footer
},
methods: {
showMenu() {
console.log("clicked");
}
}
}
</script>
components/header/header.vue
-- I want the click function to perform an action inside this component
<script>
export default {
data() {
return {
showMenuBar: false
}
},
}
</script>
Why are you worried about passing a function around?
When you emit the show-menu event simply toggle a piece of data in your parent component like this:
<template>
<div>
<app-header :showMenuBar="showMenuBar" />
<Nuxt />
<app-footer #show-menu="showMenu"/>
</div>
</template>
<script>
import header from "~/components/header/header";
import footer from "~/components/footer/footer";
export default {
components: {
'app-header': header,
'app-footer': footer
},
data() {
return {
showMenuBar: false;
};
},
methods: {
showMenu() {
// I would make this more dynamic than always
// hardcoding it to true, but you get the idea
this.showMenuBar = true;
}
}
}
</script>
Then in your AppHeader simply take it in as a prop:
<script>
export default {
props: {
showMenuBar: {
type: Boolean,
default: false,
},
}
</script>
You can declare any attribut on your parent component:
data() {
return { toBeWatched: 0 };
}
Then pass it like a props from the parent to the header child:
<app-header :Trigger="toBeWatched" />
When you listen to the #show-menu event (comming from footer child),
make any change on your attribut:
<app-footer #show-menu="toBeWatched++" />
Finally you can watch for this change on your header child and
trigger your function.
<script>
export default {
data() {
return {
showMenuBar: false
};
},
props: ['Trigger'],
watch: {
Trigger() {
this.showMenuBar = !this.showMenuBar; // or do whatever you want
console.log('showMenuBar : ' + this.showMenuBar);
}
}
};
</script>

Vue.js: Import class with function and call it in child component

I have a component my-parent. In this component, I use a child component my-child and import an external class MyClass with an own function exportedFunction. I tried to use this solution: VueJS accessing externaly imported method in vue component
Basiclly, I use mounted and the name of the function from the imported class. In methods I defined a new method, which calls the mounted one from the imported class. Than I pass the created method as property to my child, where I try to call the function with a #click and pass the parameter there.
Here is my code so far:
my-parent template:
<template>
<my-child :exportedFunction="callFunction"></my-child>
</template>
<script>
import MyClass from './MyClass';
export default {
mounted() {
exportedFunction()
},
methods: {
callFunction() {
exportedFunction()
}
}
}
</script>
my-child template:
<template>
<button #click="exportedFunction('hello world!')">Click me!</button>
</template>
<script>
export default {
props: ['exportedFunction']
}
</script>
MyClass code:
export default class MyClass {
exportedClass(parameter) {
console.log(parameter) // expected 'hello world' from child
}
}
Hope for some help!
I would ditch your MyClass component and instead have:
my-parent
<template>
<my-child :triggerEvent="callFunction"></my-child>
</template>
<script>
export default {
methods: {
callFunction() {
console.log('hello');
}
}
}
</script>
my-child
<template>
<button #click="$emit('triggerEvent')">Click me!</button>
</template>
As you want to use MyClass in your example you can keep it as is and have my-parent as:
<template>
<my-child :triggerEvent="callFunction"/>
</template>
<script>
import MyChild from "./MyChild";
import MyClass from "./MyClass.js";
export default {
components: {
MyChild
},
data() {
return {
myCls: new MyClass()
};
},
mounted() {
this.myCls.exportedClass("hello my class");
},
methods: {
callFunction() {
console.log("hello");
}
}
};
</script>

How do I reference a Svelte component's parent component?

Per the Svelte documentation on Props I am using props to pass a reference to the parent component to a child.
Props, short for 'properties', are the means by which you pass data down from a parent to a child component
That's exactly what I want to do. Here is a Svelte REPL with my code, that is also copied below:
My parent is App.html:
<div class='widget-container'>
<Widget foo bar="static" {baz}/>
</div>
<script>
import Widget from './Widget.html';
export default {
data: function(){
return {
baz: 'click me and check the console'
}
},
components: {
Widget
}
};
</script>
The child component is Widget.html:
<p>foo: {foo}</p>
<p>bar: {bar}</p>
<p>baz: {baz}</p>
<script>
export default {
oncreate: function(){
window.document.body.addEventListener('click', function(event){
console.log(`Clicked!, ${baz}`)
});
}
}
</script>
Thanks to the props, the HTML <p> elements can clearly reference the parent. However how can I reference the values in the parent component in the child component's JavaScript?
Inside lifecycle hooks and methods, access state with this.get():
<p>foo: {foo}</p>
<p>bar: {bar}</p>
<p>baz: {baz}</p>
<script>
export default {
oncreate: function(){
window.document.body.addEventListener('click', () => {
const { baz } = this.get();
console.log(`Clicked!, ${baz}`)
});
}
}l
</script>

Dynamically loading child components in parent component

I am a beginner in Vue.js so please bear with me. I created two child components and one parent component. I am able to load both the components in the parent components. Now, one of my child component should load in the parent component by default. It will have a link, and when clicked, it should load the other child component within the same parent component, by passing and ID value from itself to the loading component. Below is my code.
Parent component (App.vue):
<template>
<div id="app">
<body>
<main>
<div class="main-body">
<component v-bind:is="currentComp">
</component>
</div>
</main>
</body>
</div>
</template>
<script>
import HomeContent from './components/HomeContent.vue';
import DetailContent from './components/DetailContent.vue';
import { changeRoute } from './main.js';
export default {
name: 'app',
data() {
return {
currentComp: 'HomeContent'
};
},
components: {
HomeContent, //this is the default child component
DetailContent, //this is the other child component which should get loaded dynamically
},
created() {
changeRoute.$on('switchComp', comp => {
this.currentComp = comp;
})
}
}
</script>
Default child component (HomeContent.vue):
<template>
<div>
This is Default child component
Click to load the other child dynamically
</div>
</template>
<script>
import { changeRoute } from '../main.js';
export default {
name: 'HomeContent',
props: {
msg: String
},
methods: {
switchComponent(comp) {
changeRoute.$emit('switchComp', comp);
}
}
}
</script>
The other child component (DetailContent):
<template>
<div>
This is the other loaded child component.
</div>
</template>
<script>
export default {
name: 'DetailContent',
props: {
msg: String
},
mounted(){
alert('mount ok');
}
}
</script>
With the above approach DetailContent get loaded on click of a link from the HomeContent. Now, how can pass some data (e.g. ID = 1) from HomeContent to DetailContent. Any help with this please?

Call a function in imported child component on click from a parent element?

Is it possible to call a function in an imported component from "parent element"? Because I have a few modules that I wanna have in my app and show them dynamically in my app. I though if I import a component like Header in my main App.vue folder it will recognize the function from the main App.vue folder.
Example of App.vue:
<template>
<div>
<div class="m-grid m-grid--hor m-grid--root m-page">
<!-- <loader></loader> -->
<mobile-menu-partial></mobile-menu-partial>
<header-partial></header-partial>
<div :is="currentComponent"></div>
<div v-show="!currentComponent" v-for="component in componentsArray" :key="component.id">
<button #click="swapComponent(component)">{{component}}</button>
</div>
<button #click="swapComponent(null)">Close</button>
<footer-partial></footer-partial>
</div>
</div>
</template>
<script>
import Loader from '#/components/partials/Loader.vue'
import MobileMenu from '#/components/partials/MobileMenu.vue'
import Header from '#/components/partials/Header.vue'
import Footer from '#/components/partials/Footer.vue'
export default {
data () {
return {
currentComponent: null,
componentsArray: ['dashboard', 'schedule', 'locations', 'mileage']
}
},
name: 'App',
components: {
'loader': Loader,
'mobile-menu-partial': MobileMenu,
'header-partial': Header,
'footer-partial': Footer
},
methods: {
swapComponent: function (component) {
console.log('component', component)
this.currentComponent = component
if (component === null) {
console.log('anywhere_main')
this.$router.push('/')
} else {
this.$router.push('/' + component)
}
}
}
}
</script>
<style>
</style>
So can I have access of the function swapComponent in my header-partial? Because there are my modules for opening.
Calling child component's method from parent component
Say you have a child-comp component and want to call its childMethod method from the parent.
Use ref="someVariableName" on the parent's template and this.$refs.someVariableName on the parent's JavaScript.
Parent's template:
<div id="app>
<child-comp ref="myChild"></child-comp>
<button #click="callChildMethod">GO</button>
</div>
Parent's JavaScript code:
{
data: // ...
// ...
methods: {
callChildMethod: function () {
this.$refs.myChild.childMethod();
}
}
Calling parent's method from child
Emit an event in <child-comp> and listen to it in parent.
Parent's template (listening to an event):
<div id="app>
<child-comp #eventname="parentsMethod"></child-comp>
</div>
Notice that #eventname="parentsMethod" is the same as v-on:eventname="parentsMethod".
Parent's JavaScript code:
{
data: // ...
// ...
methods: {
parentsMethod: function (event) {
console.log('parent called', event);
}
}
Child's JavaScript code:
{
data: // ...
// ...
methods: {
someChildMethod: function () {
this.$emit('eventname', {some: 'object value'});
}
}
Now whenever, at the child, you call someChildMethod it will trigger the event and, since the parent is listening to it, it will execute parentsMethod in the parent.

Categories

Resources