Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kakallatt's avatar

Call a component from another component

I have an Alert component like in this video: https://laracasts.com/series/learning-vue-step-by-step/episodes/21 And I have another component (Book). When a book was created how can I call Alert component in the success callback function like this:

<alert>A book was created successfully !!!</alert>

I am a newbie in using vue.js. Thank you for your help.

0 likes
12 replies
vrtrainer's avatar

@kakallatt How do you handle the creation of the book on the frontend?

Do you make the POST request the usual way, when submitting the form, or by binding form values with v-model and then using vue-resource or Ajax to post the data?

In Jeffreys lession, he is building his alert component to be used when flashing messages with sessions, like you would when flashing messages to regular Laravel Views.To follow along with his example I would recommend that you submit your form "the usual way", without vue-resource or Ajax. You can then use his session->flash('message') example, in the store method of your controller, when redirecting back to the index page of your books, after saving the book to the database.

1 like
kakallatt's avatar

@johngun This is my code. I am using vue-resource. I have an alert component, how can I call it after submit successfully.

submit: function () {
    this.$http.post('/api/books/add', {
        data: this.data,
    }).then(function (response) {
        // I want to use Alert component right here to notice to users.
    }, function (response) {
    });
}
1 like
mehany's avatar

@kakallatt try

<alert v-ref:alert>A book was created successfully !!!</alert>

then when you execute the submit function

......
}).then(function (response) {
    // access the alert component like this
    this.$refs.alert
}
......

You can add a method on the alert component that will set the data variable show to true.

reference

kakallatt's avatar

@mehany It's not work.

I insert <alert v-ref:alert>A book was created successfully !!!</alert> in Book component like this:

// resources/assets/js/components/Book.vue
<template>
    .....
    <alert v-ref:alert>A book was created successfully !!!</alert>

    //Create book form
    ....
</template>

<script>
    export default {
        methods: {
            submit: function () {
                    this.$http.post('/api/books/add', {
                    data: this.data,
                }).then(function (response) {
                     this.$refs.alert
                }, function (response) {
                });
    }
</script>
mehany's avatar

@kakallatt this.$refs.alert is how you access the component. try

           ........
    }).then(function (response) {
                 console.log(this.$refs.alert);
            },
          .......

then you should see the alert component properties ( methods, data, props etc..) . I suggested that you add a method on the alert component like so

 ........
methods : {
    flash : function(){
        return this.show = true;
    }
}

........

and this should display the alert message. Make sure you register your component correctly though. From your Vue root do something like this

var parent = new Vue({
    el : "body",
    components : {
        "alert"      : alert
    },
})

Unfortunately I am not caught up with webpack so I can not show you example code with that. Hope this help!

1 like
kakallatt's avatar

Thank you so much but I don't understand your answer. Simply, I am using veuify and in the main.js I have 2 components:

var Vue = require('vue');

Vue.use(require('vue-resource'));

Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#_token').getAttribute('content');

import Explorer from './components/Book.vue';
import Alert from './components/Alert.vue';

new Vue({

    el: 'body',

    components: {Book, Alert}

});

This is my Alert.vue:

<template>
    <div class="Alert Alert--{{ type | capitalize }}"
         v-show="show"
         transition="fade"
    >
        <slot></slot>

        <span class="Alert__close"
              v-show="important"
              @click="show = false"
        >
            x
        </span>
    </div>
</template>

<script>

    export default {
        props: {
            type: { default: 'info' },
            timeout: { default: 3000 },
            important: {
                type: Boolean,
                default: false
            }
        },

        data() {
            return {show: true};
        },

        ready() {
            if (!this.important)
            {
                setTimeout(
                    () => this.show = false,
                        this.timeout
                    )
            }

        }
    }

</script>

<style>
    .Alert {
        padding: 10px;
        position: relative;
    }

    .Alert__close {
        position: absolute;
        top: 10px;
        right: 10px;
        cursor: pointer;
    }

    .Alert--Info {
        background: #e3e3e3;
    }

    .fade-transition {
        transition: opacity 1s ease;
    }

    .fade-leave {
        opacity: 0;
    }
</style>

And in another component (Book.vue), I want to call the alert component by using this code: <alert>A book was created !!!</alert>. But It just showed a origin text: A book was created !!!

// resources/assets/js/components/Book.vue
<template>
    .....
    <alert >A book was created !!!</alert>

    //Create book form
    <form> .... </form>
</template>
mehany's avatar

np, I try to elaborate. Try to add a method on the Alert component so the entire component will look like this

      export default {
     props: {
         type: { default: 'info' },
         timeout: { default: 3000 },
         important: {
             type: Boolean,
             default: false
         }
     },
 
     data() {
         return {show: true};
     },
     methods : {
         flash : function(){
             return this.show = true;
         }
     },
 
     ready() {
         if (!this.important)
         {
             setTimeout(
                 () => this.show = false,
                 this.timeout
         )
         }
 
     }
 }

Then the alert component is name Alert so it should be called this way

 this.$refs.Alert 
 // instead of 
  this.$refs.alert

then

// resources/assets/js/components/Book.vue
 <template>
 .....
 <alert v-ref:Alert>A book was created !!!</alert>
 
 //Create book form
 <form> .... </form>
 </template>

now call the flash method like this

 this.$refs.Alert.flash();

If this is not working, can you show me what console output you get after the ajax call

<script>
export default {
    methods: {
        submit: function () {
            this.$http.post('/api/books/add', {
                data: this.data,
            }).then(function (response) {
                this.$refs.Alert.flash(); 
                console.log(this.$refs.Alert); // this output
            }, function (response) {
            });
        } 
 </script>

Edit: @kakallatt added how to call the flash method

1 like
vrtrainer's avatar
Level 15

@kakallatt Ok I understand what you are trying to do now.

One thing first. Components in VueJs have isolated scopes, you are importing an referencing both components in your main.js (parent). So right now, the book component doesn't know that the Alert component exists and vice versa.

From your example you want to use your Alert inside your book component. In this case you could import it, like you did in the parent, inside the book component, like this:

// resources/assets/js/components/Book.vue
 <template>
 .....
 <alert>A book was created !!!</alert>
 
 //Create book form
 <form> .... </form>
 </template>

<script>
 import Alert from './Alert.vue';

export default{
    components:{
         'alert':Alert
    }

}

</script>

Now the Alert component will be a part of the Book component and you can use the tags inside this components template, since this is now part of the Book components scope.

Keep in mind though, your alert component is built to be shown after a page load, so you're have to make some changes to make this work, but try to make these changes first and see if the alert is showing upon page load, then we will tackle the next changes later ;-)

6 likes
mehany's avatar

@johngun sounds like a combination of your answer and mine will help @kakallatt. the v-ref addresses the isolate scope, right? . As I noted above, the alert component should be registered correctly in order for this to work.

1 like
vrtrainer's avatar

@mehany Yes it could be used to address the isolated scope, but then the parent needs to hold a reference to the component to tell it what to do and in my opinion, thats not as great. I would rather use props, events or a shared state, to get data into the childs scope.

I think @JeffreyWay is addressing the use of v-ref and the downside of this, versus using events or props, in one of his videos ?

2 likes
ssmulders's avatar

@johngun YES! Thank you. This was alluding me all day and your answer is simple and easy to replicate in a project. Been wrapping my head around Vue and learning how to use components in other templates will make all the difference :-)

Now I'm able to use an <ajax-form> anywhere I want :D

1 like

Please or to participate in this conversation.