Trigger child function in parent component - vue.js

I have a component Base.vue with a child Component that is being displayed by router-view. In the child component I have a function in my setup(), but I want the function to be triggered by menu item in Base.vue. How can I achieve this in vue 3? I can't use vuex for this, because the function uses a lot of google map things and refs.
Base.vue router-view Component <- component contains another component which I need to use the function from in Base.vue

This can be easily implemented through the Vue Composition Api
Assign a ref to your child component as such
<child-component ref="childRef"></child-component>
Declare the ref in your setup function as
import { ref } from 'vue'
export default {
components: { },
props: {},
setup(context,props) {
const childRef = ref(null)
return {childRef}
}
}
You can now call functions in your child component by leveraging your childRef, inside the setup function childRef.value.childFunction() can call functions declared in your child component

Related

How to get all the props that a parent component has inside a child component In vue js?

How to get all the props like $store, $parent, $root everything that a parent component has inside a child component?
So I'm creating a parent component and a child.
However I don't have anything to render within the child. So I'm creating a renderless child component.
However I'm programatically inserting new html elements via child component
following piece of code is the parent component where I mount the child component.
This is the method I found online.
This is working fine. But I'm not getting the props like this.$store , this.$parent and all (which are automatically available inside the parent component) in the child component.
import { Child } from "./components/child";
export default {
name: "parent",
components: {},
props: [],
data() {
return {};
},
computed: {},
created() {
new Child().$mount();
},
mounted() {},
methods: {},
};
This is the child component.
import Vue from "vue";
const CHILD = {
name: "child",
components: {},
props: [],
data() {
return {};
},
render() {
return;
},
computed: {},
created() {},
mounted() {},
methods: {},
};
export const Child = Vue.extend(CHILD);
So the basic idea is to create child component classes having all the options like $store $el and all (everything vue provides).... but instead of instantiating it inside the template I want to instantiate them in the parent component like this: new Child({...props}).
So is that possible. I'm doing this because my child components are renderless. (But within the child components I'm creating Dom elements..., & the reason I want to extend all the functionalities provided by vue is because in that way I don't want to write my own store, my own event emitter, my own prop binder.... everything will be automatically available...)
KEY TAKEAWAY is that I want to create Child components manually like by calling new Child() rather than registering them as components inside the parent as components: {'app-child': Child} and instantiating them inside the parent template ... Along with that I want every functionalities provided by vue inside the child component.. something like extending vue..
Also How can I listen to events from the child created as above ...
something like this.
// child
created() {
this.$emit('event')
}
//parent
mounted() {
this.child.$on('event', console.log)
}
sources:
https://css-tricks.com/creating-vue-js-component-instances-programmatically/
https://css-tricks.com/building-renderless-vue-components/

Dynamic component inside a component that is rendered with render() function

I saw in the docs that you can have a dynamic component inside your VueComponent like this :
<component :is="componentName" v-bind="componentProps" #custom-event="doSomething" />
I am trying to have one of these dynamic components inside a dynamically rendered component (with the render() function, not with an HTML template). Without too much hope, I've tried this :
render(createElement: CreateElement) {
return createElement('component', props: {
'is': 'TestComponent'
});
}
but I got
[Vue warn]: Unknown custom element: <component> - did you register the component correctly?
So again, not hoping too much for a miracle, I tried to import Component and declare it as a component :
#Component({
components: {
Component,
TestComponent
}
})
export default class DynamicThingy extends Vue {
render(createElement: CreateElement): VNode {
return createElement('Component', {
props: {
'is': 'TestComponent'
}
});
}
}
But then I get
[Vue warn]: Do not use built-in or reserved HTML elements as component id: Component
Any idea how that could be possible ?
The first parameter of createElement() must be either
An HTML tag name,
component options,
or async function resolving to one of these.
https://v2.vuejs.org/v2/guide/render-function.html#createElement-Arguments
So in a render function, you can simply create a function* that returns one or another component's options based on your desired criteria, and let that be your first argument. *This function is identical to the function you'd write to determine what goes into the :is prop)
You only need the dynamic component <component /> and :is prop in a template where you don't have the possibility to do it programmatically.
You can use this smart-list component from the vue docs as an example.

Pass change to child components when data value in parent component is changed in vuejs

I want to pass down the changes made in parent component data values to its child components each time the value changes in parent how can i achieve it in vue.js. I am using 3 custom components that have to reflect the current value of the parent component each time. p.s i am new to vue.js
you just need to pass it as a prop. In your template:
<my-component :my-prop="myData" />
and in your script tag:
export default {
data() {
myData: 0,
}
}
Whenever you update this.data, the component will update its view, as the prop will have changed
Data is typically passed one-way from parent to child components via props. See the documentation on this here.
Example:
// register the child component
Vue.component('child', {
props: ['myProp'],
template: '<span>{{ myProp }}</span>'
})
// in parent component
<child :my-prop="hello"></child>

Pass information from a child component to a parent component with Vue.js

Thanks for reading my question.
I have doubts about how to accomplish this in my Vue.js app.
Parent Component: App.vue
Child Components: Loading.vue, ProductsList.vue, NoProductList.vue
The App component is the container. When the page loads, the Loading component is displayed.
The Loading component then checks for products. If there are products the Loading component will return the products as an object.
If there aren't any products the Loading component will return null.
How do I tell the App component which component to use based on the Loading components return value? ie.. Load the ProductsList component if there are products and the NoProduct component when there aren't any products?.
What's the correct way to do notify the parent component about which component it should use in Vue?
Should I use $emit (pass data from child to parent), State Management https://v2.vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch or a Bus component?
Some code...
Loading.vue component (child):
export default {
name: 'loading',
data () {
return {
message: ''
}
},
mounted: function () {
this.loadingProcess();
},
methods: {
loadingProcess: function () {
//process
this.$emit('found-products', 'hola');
}
}
App.vue component (parent):
<template>
<div>
<div id="resultComponent" #found-products="checkProductsList">
<loading></loading>
...
</div>
</div>
</template>
Thanks in advance.
For parent-child interactions, the correct way is for the child to $emit and the parent to set props.
State management and buses are for more complex systems where data must be shared by not-closely-related components.

Is there a thing in Vuex that work the same as mapDispatchToProps in Redux?

I was trying to do things like this.updateData() instead of this.$store.dispatch() in a child component, where the updateData is a function inherits from its parent component. Anyone have any idea how to achieve that?
So to update data of parent comp. from child component in Vue we can utilize event bus:
Parent:
<template>
Hi Blake...
<child-component #trigger="updateData()"></child-component>
</template>
<script>
export default {
mounted() {},
methods: {
updateData: function() {
// this will be triggered from child
}
}
}
</script>
Child ( child-component ):
<template>
<button #click="$emit('trigger')">Trigger Parent Function</button>
</template>
<script>
export default {
mounted() {}
}
</script>
Now this only triggers parent function but you can also send data with event that will be received by parent. This is just Vue without Vuex. If I'm wrong and you're not looking for this maybe you want to use Vuex mapActions which can be used to import all Vuex actions you need in your component and use them as this.vuexAction instead of this.$store.dispatch('vuexAction').
I hope I helped. Good luck.