Value from other Vue component - vue.js

How can I get the value of an element in another Vue component and use it in another Component. For example I want to get the value of a textbox from a separate component and use it another.

By using event bus to communicate between any components,
Component A:
<script>
export default {
name: 'ComponentA',
methods: {
onTextAreaChange: function(event) {
this.$root.$emit('changed', event)
}
}
}
</script>
Component B:
<script>
export default {
name: 'App',
mounted() {
this.$root.$on('changed', (data) => {
//...console data here
})
}
}
</script>

Related

Send data from child to parent using VueJS

I'm working on a small project using Django and VueJs. Everything is good, I'd just like to know how I can send data from my component (Modal) to another one after making an Axios request? This is my code:
NB: Please read my code comments to understand what I want to do.
Child : AddContact.vue
methods: {
post(){
getAPI.post('api/contact/post/', this.form).then((response) => {
// here I want to send response data to Contact.vue
}).catch((error) => {
})
}
}
Parent : Contact.vue ( where I want to receive data )
<template>
<addContactModal></addContactModal>
</template>
<script>
import addContactModal from "../modals/contact/addContact.vue";
import { getAPI } from '../../../vue/src/axios-api';
export default {
name: 'Contact',
components: {
addContactModal: addContactModal
}
};
</script>
You can emit a signal from the child component:
getAPI.post('api/contact/post/', this.form).then((response) => {
this.$emit('loaded', response) // emit your signal
}).catch((error) => {
// handle error
})
And then you bind a method of the parent to the signal. Note that:
the name of the signal ($emit's first arg) and the one of the # directive must match (# is short for v-on)
the second argument passed to $emit will become the first argument of the bound function
<template>
<addContactModal #loaded="doSomethingWithResp"></addContactModal>
</template>
...
<script>
import addContactModal from "../modals/contact/addContact.vue";
import { getAPI } from '../../../vue/src/axios-api';
export default {
name: 'Contact',
components: {
addContactModal: addContactModal
},
methods: {
doSomethingWithResp: function (response) {
console.log(response)
}
}
};
</script>

How to hook lifecycle events from root App component in Vue.js

The structure of the app:
src/
|-- App.vue
|-- components/
|-- MyComponent.vue
|-- OtherComponent.vue
If I do, in MyComponent.vue
// MyComponent.vue
export default {
name: 'MyComponent',
methods: {
mounted() {
alert('MyComponent mounted')
}
}
}
This works as expected — an alert box is triggered when the component is mounted.
However, if I do the exact same thing in App.vue:
// App.vue
import MyComponent from './components/MyComponent.vue'
import OtherComponent from './components/OtherComponent.vue'
export default {
name: 'app',
components: {
MyComponent,
OtherComponent
},
methods: {
mounted() {
alert('app mounted')
}
}
}
Then nothing happens. I've tried with created, mounted, I've also try to wrap the alert() call into this.$nextTick({ ... }) — no success.
My problem is: I want something to happen (in this example, alert('app mounted')) once the child components have been mounted, because this "thing" needs to have all components mounted before executing.
Is it possible to hook a lifecycle event (ideally, mounted) in the App component?
All lifecycle methods need not to be declared within methods.
Should be as below.
// App.vue
import MyComponent from './components/MyComponent.vue'
import OtherComponent from './components/OtherComponent.vue'
export default {
name: 'app',
components: {
MyComponent,
OtherComponent
},
mounted() {
alert('app mounted')
},
methods: {
}
}
For more details read here
mounted is life cycle method of vue component. don't put it in methods.
Change
// MyComponent.vue
export default {
name: 'MyComponent',
methods: {
mounted() {
alert('MyComponent mounted')
}
}
}
To
// MyComponent.vue
export default {
name: 'MyComponent',
methods: {
},
mounted() {
alert('MyComponent mounted')
}
}

Vue: Make a child component be aware of a change in a property modified by its parent

I have a child component that's basically a search box. When the user types something and presses enter, an event is fired that goes to the parent with the search topic:
export default {
name: "SearchBar",
methods: {
searchRequested(event) {
const topic = event.target.value;
this.$emit('searchRequested', topic);
}
}
};
The parent receives the event and updates a prop connected to other of its children (an image gallery):
<template>
<div id="app">
<SearchBar #searchRequested="onSearchRequested($event)" />
<Images :topic="topic" />
</div>
</template>
<script>
import SearchBar from './components/SearchBar.vue'
import Images from './components/Images.vue'
export default {
name: 'app',
components: {
SearchBar,
Images
},
data() {
return {
topic: ''
};
},
methods: {
onSearchRequested(topic) {
this.topic = topic;
}
}
}
</script>
So far, so good. But now I want the child component load itself with images related to the searched topic whenever the user performs a new search. For that, the child component Images must be aware of a change on its property topic, so I created a computed one:
import { ImagesService } from '../services/images.service.js';
export default {
data() {
return {
topic_: ''
};
},
methods: {
updateImages() {
const images = new ImagesService();
images.getImages(this.topic_).then(rawImages => console.log(rawImages));
}
},
computed: {
topic: {
get: function() {
return this.topic_;
},
set: function(topic) {
this.topic_ = topic;
this.updateImages();
}
}
}
};
But unfortunately, the setter never gets called. I have to say I'm new in Vue, so probably I'm doing something wrong. Any help will be appreciated.
You don't need to create computed in the main component. Images component is already aware of the changes in the topic prop.
You need to watch the changes of topic and do an async operation in 'Images.vue'. It's possible with Vue's watchers.
Vue docs watchers
'./components/Images.vue'
<template>...</template>
<script>
export defult {
props: ['topic'],
data(){
return {
images: []
}
},
watch: {
topic(newVal){
// do async opreation and update data.
// ImageSerice.get(newVal)
// .then(images => this.images = images)
}
}
}
</script>

Vue.js parent-child components , why my prop is not yet available in child component?

In a parent component Member.vue , I get the user and account data from Vuex store via getters
<script>
import { mapGetters } from 'vuex'
import Profile from '#/components/Member/Profile.vue'
export default {
name: 'member',
components: {
Profile
},
data () {
return {
}
},
computed: {
...mapGetters(['user', 'account'])
},
methods: {
},
created () {
console.log('MEMBER VUE CREATED user: ', this.user)
console.log('MEMBER VUE CREATED account: ', this.account)
}
}
</script>
In the child component profile , I get the user data from props, but it's undefined ...
<script>
export default {
name: 'profile',
props: ['user'],
computed: {
...
},
methods: {
...
},
created: function () {
console.log('user data from parent component:')
console.log('user: ', this.user)
}
}
</script>
I guess it's related to the Parent-Child lifecycle hooks... but I don't see actually how to solve it easily ... thanks for feedback
In your HTML you need to pass the property down to the children, in your case it would be something like:
<profile :user="user" ...></profile>

Call a method of another component

How to call a method of another component ?
Like I have a component named Modal.vue . I have a method like below
<script>
export default {
name: 'modal'
methods: {
getUsers() {
//some code here
}
},
created: function () {
this.getUsers();
}
}
</script>
I would like to call that method in another component named Dashboard.vue.
<script>
export default {
name: 'dashboard'
methods: {
add_adddress () {
this.getUsers(); // I would like to access here like this
//some code here
}
},
}
</script>
I read this question, but how can I use $emit,$on,$broadcast in my current setup ?
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>