2
votes

I want to know how can I pass variables to vue component in laravel?

When we work with blade we can pass variables like:

$now = Carbon::now();
return view('xxxxxxxx', compact('now');

That way I can use $now in xxxxxxxx blade file. But what about vue components? we usually return data by json for components and with axios route we get that info no way to specify such data for exact component of us?

What if I want to use $now = Carbon::now(); in single.vue component?

How can I make that happen?

Update

Here is what I want to do with timing as carbon cannot be used (based on comments) I want to use moment.js

Logic

  1. Let users bid if project deadline hasn't arrived
  2. Don't let users bid if project deadline has arrived

template

<template v-if="`${project.deadline | timeAgo}`">
  pssed (will be replaced by button is just for test)
</template>
<template v-else>
  still have time (will be replaced by button is just for test)
</template>

script

var moment = require('moment');
export default {
        data(){
            return {
                project : '',
            }
        },
        mounted: function() {
            // I found this code by google not sure if is currect!
            Vue.filter('timeAgo', function(value){
                return moment(value) >= fromNow()
            });
        },
}

Based on my code above here is the results

one

1
can't you use, i.e., moment.js or DateTime for that? anyway, there's php vars to JavaScript var package for Laravel by Jeffrey Way, I think you can use that and pass the variable to your component? Or just json encode and decode the php var into your component.Wreigh
@Wreigh i am using moment.js currently in my component but is hard to do functions with it (at least for me!) for example i want to not let users do certain action after specific time reached (database based) with moment I have no idea how to do it while with carbon was piece of cake :\mafortis
ah, so, you want to use a Carbon object in Javascript together with its methods? I think that's not possible. because you'll have to serialize the whole PHP class for you to be able to use it, plus Carbon uses PHP's DateTime class I believe. What example functions do you want to use?Wreigh
Would you mind to show your Vue component file? I'll be glad to help :Dkrisanalfa
@krisanalfa updated my qustion bro,mafortis

1 Answers

0
votes

Try this:

This is my routes, simply I just render a view with some pre-defined variables

Route::get('/', function () {
    return view('welcome', [
        'now' => Carbon::now(),
        'deadline' => Carbon::now()->addHours(2)
    ]);
});

And this is my view file. Here I have custom element named: example-component. And this is how I passed PHP variables to Vue component using props.

And pass your data to window like so:

<script>window.data = @json(compact('now', 'deadline'))</script>

And this is my Vue component file:

<template>
    <h1>
        <span v-if="isPassed">This job is passed</span>
        <span v-else>You have to finish this job</span>
        {{ parsedDeadline | timeFromX(parsedNow) }}
    </h1>
</template>

<script>
const moment = require('moment');

export default {
    props: {
        now: {
            type: String,
            default: () => window.data.now.date // since `now` is an object, you need to access the `date` property to get plain string date that moment can parse
        },
        deadline: {
            type: String,
            default: () => window.data.deadline.date // same as above
        }
    },
    computed: {
        parsedNow () {
            return moment(this.now)
        },
        parsedDeadline () {
            return moment(this.deadline)
        },
        isPassed () {
            return this.parsedNow.isAfter(this.parsedDeadline)
        }
    }
}
</script>

Here's the documentation about computed and filters. You may NEVER add a filter in a mounted function since it may leads to memory leak. Here's how I add my filter. In your app.js (assumed you're using default Laravel Vue preset)

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

Vue.component('example-component', require('./components/ExampleComponent.vue'));

Vue.filter('timeFromX', (a, b) => a.from(b)); // TADAAA...!!!

const app = new Vue({
    el: '#app'
});

UPDATE

If you want to try this, you may edit the routes/web.php and change the deadline value:

Route::get('/', function () {
    return view('welcome', [
        'now' => Carbon::now(),
        'deadline' => Carbon::now()->subHours(2), // Passed 2 hours ago
        // 'deadline' => Carbon::now()->addHours(2), // In 2 hours
    ]);
});

Checkout the Carbon docs here about addition and subtraction.

UPDATE II

If you got error in app.js from the code above, maybe your transpiler doesn't know about arrow-parens.

// Looks like arrow-parens not working, see code below
// Vue.filter('timeFromX', (a, b) => a.from(b)); // TADAAA...!!!

// Change it to this ???
Vue.filter('timeFromX', function (a, b) {
    return a.from(b);
});