In the compoent ,when call $emit('callback', params) finished, I need the returned value. Someone can help?
vueComponent:
methods: {
test: function () {
if(this.$emit('cb', param1)){
// this not working
console.log('return true')
}else{
console.log('return false')
}
}
}
vueRoot:
methods: {
cb: function () {
return true;
}
}
As per my comment below the original question, $emit only tells the parent component that an event has occurred and allows it to do something in response to the event and any data sent with it. The child component has no way of knowing what the results of the parent's actions are. In order to tell the child component something after the callback finishes, you will need to send that value through a prop and have the child watch for any changes to the prop's value.
Related
The method must return a Promise
That promise must be new on or after nextTick
So basically I need a method that starts executing before a tick and returns a value that is calculated after a tick.
methods:{
myMethod: function(){
// change this.$data effecting a computed val that is injected into a subelement prop
//tick
//grab the subelement by this.$ref
//return something from that subelement that has been efected by the computed change
}
}
To achieve what you want, you could use an async function:
async myMethod() {
this.foo = "sup";
await this.$nextTick();
console.log(this.$refs.subelement.count);
}
An async function returns a promise, and allows you to use await to wait for any specified promises to resolve before continuing. I created a simple example of this on CodeSandbox here: https://codesandbox.io/embed/vue-template-6qny6.
If you want to execute code in response to an element being re-rendered or changed, it would be better to emit an event from that child component and listen to that event from the parent. Or, if you need that computed property in both the child and the parent, you could pull the logic for it out into the parent component and pass it down as a prop.
primaryPromise: function(foo, bar) {
// changing foo impacts computed props
// some of those computed things effect the sub element bar
this.foo = foo;
return new Promise((resolve, reject) => {
// a tick grants the time required for the
// computed changes in foo to propagate into bar
this.$nextTick(() => {
// the resulting sub-promise resolution
// takes computed changes into account
resolve(this.$refs[bar][0].subPromise());
});
});
},
I am not sure when computed property (in vue lifecycle) comes. Let's say I have a method that I run in created() as:
created () {
getSomething()
}
Inside getSomething() I fetch data and fill my data property as:
getSomething(){
axios.get(...) { this.info = response.data }
}
Now, in computed properties, I do:
computed: {
doSomething () {
this.info.forEach(item => {})
}
}
But, inside my computed I get forEach is undefined, as if this.info is not an array or has not be filled.
What am I doing wrong? are computed props called before created() or something?
try something like this
getSomething(){
return axios.get(...) { this.info = response.data }
}
then you can use the promise returned in created method like this....
created () {
getSomething().then( () => {
doSomething()
}}
}
You could utilise Vuex' state management...
Vuex has :
Dispatches
Actions
Mutations
Getters
What i am thinking is, on your page load, map an action to the store that makes a call to your axios service and after it returns, commit a mutation that stores the response to the store...
then you can map the state to your component and retrieve the data.
This might not be the quickest answer but if you are expecting to need the response data from the axios request, it might be worth putting it into some sort of state management :-)
In my App, store gets updated whenever an event is dispatched. But the problem is I have a child component.
Store:
state.name = 'Jack'; //initial state value
Child Component:
this.props.updateName('Micheal');
this.printName();
printName() {
console.log(this.props.name); // 'Jack'
}
After a while I call the same function.
this.printName(); // 'Micheal'
My question is that, is there any way to callback a function in child component when store is updated?
The child component gets the new state via props. So, the componentWillReceiveProps will do the trick.
componentWillReceiveProps(nextProps) {
if (nextProps.name !== this.props.name) {
console.log(this.props.name, nextProps.name);
}
}
I have a parent component with a grid of rows and I am using vuex to pass data, as i add a new record I would want to open the newly added record in a modal window. I am emitting an event and opening the modal with the first record (index = 0). The problem is that, as it is an ajax call to add record using an vuex "action", the emit happens before the record is added. How can I wait till the record is added with event? or Is there a better way to do it?
Below is the code:
<!-- Grid Component -->
<grid>
<addrow #newrecordadded="openNewlyAddedRecord"></addrow>
<gridrow v-for="row in rows" :key="row._id"></gridrow>
</grid>
computed: {
rows(){
return this.$store.state.rows;
}
},
methods:{
openNewlyAddedRecord(){
this.openmodal(this.rows[0])
}
}
my store.js
state: {
rows : []
}
so in addrow component once the user clicks on submit form it dispatches to vuex
methods:{
onsubmit(){
this.$store.dispatch('addrow',this.newrow);
this.$emit("newrecordadded");
}
}
actions.js
addrow({ commit,state }, payload){
var url = "/add";
Axios.post(url,payload)
.then(function(response){
commit('addnewrow',response.data);
});
}
mutations.js
addnewrow(state,payload){
state.rows.unshift(payload);
}
Or alternatively can we pass a call back function to dispatch?
You can make the addrow action return a promise, like so:
addrow({ commit,state }, payload){
var url = "/add";
return Axios.post(url,payload)
.then(function(response){
commit('addnewrow',response.data);
});
}
In the onsubmit method in your component you can now do:
this.$store.dispatch('addrow',this.newrow).then(() => this.$emit("newrecordadded");)
Vue - I want to track user changes on a page and send those updates if they navigate away. The basic idea is
//child
beforeDestroy: function() {
var that = this;
axios.post('gate/cart.php', userUpdates)
.then(function(res) {
if (res.data.success) {
that.$emit('updateCart', res.data.cart);
//parent (App.vue)
<router-view
#updateCart="updateCart"
...
methods: {
updateCart: function(newCart) {
alert('caught');
this.cart = newCart;
The dev tools show me the emit is emitted and the correct payload (res.data.cart) is sent, but the parent method isn't called. (That alert doesn't trigger.) I know the updateCart method in the parent is working, as another component uses it fine like this with a regular method:
addToCart: function() {
var that = this;
axios.post('gate/cart.php', this.dataToSend)
.then(function(res) {
if(res.data.success === true) {
that.$emit('updateCart', res.data.cart)
that.$router.push({ path: '/product/' + that.product.id})
}
If the ajax is working, I get a correct $emit, and the target method is ok, what lifecycle hook caveat is stopping me from executing the parent method? Do you know a better way to do this? (I want to check the success of the ajax call before updating the parent data.)