0

I'm still a bit new to Vue.js, so I may be fundamentally misunderstanding something about the reactivity of it, but basically, I want to pass some data from PHP Laravel to a Vue.js component and have the Vue.js component automatically update when that data changes.

I've seen several similar posts on SO suggest that I use props to pass the data from a Laravel Blade template to a Vue.js component. Here's an example:
How to pass a PHP variable to Vue component instance in Laravel blade?

I have this working perfectly fine, but now I'm stuck with how to get the component to update when the data dynamically changes after page-load.

Specifically, I have a report table on a particular web page, and when the user clicks certain buttons, etc., I use Ajax to call a Laravel controller action that re-runs a query in my Laravel model to get the new data for the report.

I have the data in a PHP array / JSON, and that data is being properly returned to the client-side and I have access to it in the JS, but now, what do I need to do to force the report component in Vue.js to essentially re-render based on the data I just received? Is there a way to "update props" so that Vue.js detects the change and automatically re-renders the whole report component for me?

This is where I'm stuck, and after quite a bit of research, I can't find how to do this. Thank you.

1 Answer 1

4

Are you using Ajax outside of the Vue component? or within it as a method?

I have an example of how I dynamically update the Vue data from within the component itself. I'm not sure how to have external JS update the Vue component directly but I feel this is a good option to look at. I'm using axios instead of Ajax but the principle is the same (Axios is included by default in most Laravel installs past 5.5).

<template>
    <div>
        <div id="reports">
            <!-- Display data -->
            {{ reports }}
        </div>
        <button @click="refreshReports">Refresh</button>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                endpoint: '/api/MY_ROUTE/'
            };
        },

        props: {
            reports: Object
        },

        methods: {
            // Make Axios call to API endpoint
            refreshReports() {
                // GET version
                axios.get(this.endpoint)
                    .then(({data}) => {
                        this.reports = data.data;
                    });

                // POST version
                axios.post(this.endpoint, {
                    KEY: 'VALUE',
                }).then(({data}) => {
                    this.reports = data.data;
                });

                /*
                    `data.data` assumes the returned response is a JSON Resource

                    if it's not returning the correct data, put a `console.log(data)` and see how it's getting returned!
                 */
            }
        }
    };
</script>

Where in your routes/api.php file you have a route like this:

// GET version
Route::get('MY_ROUTE', 'ReportController@getReports');

// POST version
Route::post('MY_ROUTE', 'ReportController@getReports');

And your Controller would have some method like this:

// app/Http/Controllers/ReportController
public function getReports(Request $request) {
    return Reports::all();
}

Does that make sense?


Update:

I'm not sure how to have external JS update the Vue component directly

I know you can import external JS scripts and use their functions in methods but I've never done it that way before.

Something like:

<script>
import { myFunction } from '../external.js'

export default {
    methods: {
        refreshReports() {
            // I have no idea if this is the correct way to do it, just a guess!
            this.reports = myFunction();
        }
    }
};
</script>

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, that worked perfectly. Thank you very much. My main hangup was that I didn't know you could a) so easily access props via this, and b) I didn't think to assign the prop to a data property to get all the connectivity I wanted. Thanks again.
To add to it a bit, basically, I had a prop called report. I then created a data property called reportRows, which I set to this.report.rows by default (from props). Then, in the method, if I set this.reportRows to whatever data came back, everything instantly updated. Thanks.
Awesome, my pleasure! I added a little update at the end from someone else's answer in a different question but I haven't used that way before/nor do I know if that is the correct syntax. I always felt it was better to have my Ajax/axios call within the Vue component for readability and ease of use because Vue will detect if my data object has changed and then automatically re-draw the component with the new data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.