ndeshpande's avatar

Using Blade inside of a Vue templates properly

Is it possible to use blade functionality inside of a vue template? An example would be if I wanted to create a 'Login-Form' component: {code} {{ csrf_field() }}

                    <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">

                        <label for="email" class="col-md-4 control-label"><i class="fa fa-envelope-o" aria-hidden="true"></i> E-Mail Address</label>

                        <div class="col-md-6">
                            <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>

                            @if ($errors->has('email'))
                                <span class="help-block">
                                    <strong>{{ $errors->first('email') }}</strong>
                                </span>
                            @endif
                        </div>
                    </div>
</form>

{code}

The use of blade '{}' would obviously cause this to fail. What is the correct way doing this?

0 likes
9 replies
DmytroOlefyrenko's avatar

You can use the @ symbol to inform the Blade rendering engine an expression should remain untouched. For example,

<strong>@{{ $errors->first('email') }}</strong>
1 like
jekinney's avatar

No.

A vue component is rendered on the client side. Obviously php is is parsed on the server side.

Instead you pass data in as props. It can be a json object with many objects, string, etc.

Say you want to pass in a collection of articles, pass it in a prop:

<article-list articles="{{ json_encode($articles) }}"><\article-list>

Nice thing to add is unlike regular JavaScript and HTML data-attributes the above code is removed from the dom so those who inspect your HTML will not see a json string of your data.

So a csrf="{{ csrf_token() }}" as a prop. Probably want errors and old data too. But then you probably should just use php normally or actually use ajax call.

6 likes
ndeshpande's avatar

@jekinney thanks for the great answer! I was thinking about things incorrectly. Next step is figuring out how to pass my PHP data into my Vue templates as data.

gborcherds's avatar

@ndeshpande you can do that in your blade templates, in laravel 5.3, Taylor is already doing something similar to this.

You can either put an object in a tag in your head that is your json_encoded data, or you can put it in a hidden input and then get the data that way.

Like this

<script>
var myServerData = <?= json_encode($myServerData); ?>
</script>

Then you can access that data in your vue templates like

data() {
    return {
        myLocalServerData : myServerData
    }
}

then in your vue code you can access the server data as myLocalServerData

1 like
ndeshpande's avatar

@gborcherds I SEE! I created a new project and realized exactaly what was going on:

<script>
        window.Laravel = <?php echo json_encode([
            'csrfToken' => csrf_token(),
        ]); ?>
</script>

I found this in the default login page Taylor sets up. Really cool! Thanks for pointing this out!

jimmck's avatar

Its important to realize that using Blade is a once in an instantiation event. Once the code is emitted to the browser its done (Your javascript is active). You have no 2 way bindings to the server. The csrfToken example? What do you expect is being achieved? Blade is Wonderful for initializing your Javascript setup. You can dynamically organize and initialize your Javascript data structures. After that you need HTTP to dynamically update those data structures.

1 like
Laraveldeep's avatar

@jekinney is right

Let say our example vue component is <emailaddr></emailaddr>

Example Vue component:

<template>
    // few other things
    <p>{{ errorMessage }}</p>

</template>

<script>
export default {
    props: ['errorMessage'],
    // other stuffs

}
</script>

Example Blade:

@if($errors->has('email'))
    <emailaddr></emailaddr>
@elseif 
    <emailaddr error-message="{{ $errors->first('email') }}"></emailaddr>
@endif
3 likes
bwjoyce's avatar

I used "var myServerData = {!! json_encode($myServerData) !!};" but it worked! Thanks!

1 like

Please or to participate in this conversation.