How to target method inside other component?
I'm working on a project where I want to target a method inside another component. I press a button inside the dashboard component and I want to change the data inside my line-chart component (which uses vue-chartjs). How can I target this method?
Well you could target it over $refs however, this is pretty dirty, as it prodvides a pretty strict binding of your componentes.
A better solution would be to trigger an event (eventbus) or over an prop.
You can call children's method by referencing them through refs
In your example, your dashboard's template should looks like this :
<template>
<div>
<button #click="$refs.chart.yourMethod()">Call child method</button>
<line-chart ref="chart"></line-chart>
</div>
</template>
Related
I have a VueJS project - which in one view there are parent and child components that are both using the same component called deleteModal.
When I trigger the modal from the child (to show it), it triggers both the child and parent modals (except no data is passed to the modal triggered by the parent). As I understand it, this is because I have used the component twice - in the parent and child - example below. To note, it works as expected from the paren
I've researched and tried a few things: setting a key value for each of the components, changing the components ref name among other things. I have also tried using v-show to only show component just before I trigger the parent model however, this solution is not ideal.
How can I only trigger the modal from the child?
Parent Component
<template>
<div>
<childCompt ref="childCompt" />
<deleteModal
ref="deleteModal"
#deleteTriggerAPI="deleteAPIParent"
/>
</div>
<template>
Child Component - childCompt
<template>
<div>
<deleteModal
ref="deleteModal"
#deleteTriggerAPI="deleteAPIChild"
/>
</div>
<template>
My old answear is not good at all. I personally to show and hide element using jquery in vue. For me right now this is best solution but maybe i don't know some best.
If you want use only vue i using also variable passing to child from parent which will support visable of your modal.
We pass variable with ":" and register event with "#".
<template>
<childComponent :isModalOpen="isModalOpen" #onModalClose="isModalOpen=false">
<template>
export default {
name:"parent",
data: () => {
isModalOpen: false
}
}
In child we catch this by using props. We need to define type of varialbe we pass. Different between props and data is that in props we cannot change value in child component.
export default {
name: "child",
props: {
isModalOpen: Boolean
}
}
And you can use this variable to show or hide modal. Also in child component we can create button to close modal and we emit event to parent in order to change variable value.
To do this we using this.$emit('eventName');
More information right here: https://forum.vuejs.org/t/passing-data-back-to-parent/1201
You could try globally defining the component,
ie, in main.js
Vue.component('deleteModal',deleteModal)
I need the bounding client rect of an anchor element.
I mark that using bind:this={someVariable}
But when I add that code to a svelte component, I get some other object svelte uses to represent a component.
can I access the enclosed element or something like that from that binding?
Or do I have to wrap every component with a sacrificial <div /> and bind that?
Using bind:this does not give you a DOM Element because Svelte does not require that your component has a root element. This is a valid Svelte element:
<script>
...
</script>
<div>...</div>
<div>...</div>
And so is a component that does not have any markup at all:
<script>
...
</script>
In both those cases, it would be impossible to return a bounding client rect for these components because there is no 'root' element.
That said, what you can do is add a bind:this in your component and export that one:
<script>
export let anchor
</script>
<svelte:options accessors></svelte:options>
<a bind:this={anchor}>...</a>
And in your parent you can now get the anchor element using child.anchor (note that by default the props are not accessible this way, that's why you need the svelte:options)
One of the reason this is not so straightforward though is that it is a very 'unsvelte' way of working, you would normally not direcly interact with the markup generated by another component (that is the domain of that component).
Alternatives could be
expose the client rectangle directly instead of the element
move what you are trying to do to the anchor component itself
In jquery , I can use $(this) reference to access an element without using any class or id. What is the way to achieve similar result in vue.js?
I assume you want to get an element which triggered event. Then it should be event.target.
For example:
<div #click="sayHi"></div>
methods: {
sayHi(event) {
console.log(event.target)
}
}
The prior answer refers to this.$el which grabs the root element of a given Vue component (Vue documentation on .el), however, if you want to grab an arbitrary element within a given component, you can use this.$refs (Vue documentation on .refs):
<template>
<div>
<h1 ref="myHeader">Hello</h1>
<div>
<template>
this.$el within a Vue component
I have the following template in a specific modal component:
<template>
<my-base-modal ref="BaseModal" :width="1000">
<template v-slot:header>Details</template>
<template v-slot:body>
<detail-card ref="DetailCard"></detail-card>
</template>
</my-base-modal>
</template>
It creates a base modal and overwrites the slots for header and body.
The body slot is filled with a sub component which needs to load some data.
I tried to use the following method to open and load the content of this modal:
open (id) {
this.$refs.DetailCard.load(id)
this.$nextTick(() => {
this.$refs.BaseModal.open()
})
}
But this.$refs.DetailCard is always undefined. I suspect this is because the reference DetailCard is defined inside the body slot of the <base-modal> component?
How am I supposed to trigger a function on the <detail-card> component in this example, without using EventBus or passing some props into it?
My suspicion is that at runtime, the DOM is not rendered until the BaseModal's open method is invoked. Therefore, this.$refs.DetailCard will returned undefined since the body slot of your component has not rendered with the nested component.
As you have mentioned in the comments, the fix can be as easy as ensuring that the DOM is already rendered, e.g. using v-show instead of v-if.
I use Vue, vue-fontawesome and v-tooltip. What I simply try to do is this:
<button v-tooltip="<fa icon='sign-out-alt'/>">Upgrade</button>
But that doesn't work, component passed as strings are not rendered. How to get it done easy way?
In this specific use case, there's an example for that in v-tooltip readme
If you need to display components inside the tooltip (or
popover/dropdown, technically it's the same 😄), use the v-popover
component
Here's an example of using a child component as a popover. Instead of my child component, you would use your <fa icon='sign-out-alt'/> icon.