67

I'm doing a program using Slim 2 that uses Twig as my templating engine. so It uses the syntax {{ foo }} in php file. On the other hand, I'm using vue.js, it also uses {{ bar }}.

E.g.

I'm gonna do the two way binding, below is my html code.

<div class="container">
    Label Value: <label>{{ foo }}</label><br>
    Field Value: <input v-model="foo">
</div>

and here is my vue js code.

new Vue({

    el: '.container',
    data: {
        foo: 'Hello world.'
    }
});

So the Hello world should be in the Label Value.

The output is the image below.

enter image description here

Which it did not worked, probably the system thought it's a twig variable. So I checked by passing variable in a view.

$app->get('/', function() use ($app) {
    $app->render('login.php', [
        'foo' => 'FROM PHP FILE'
    ]);
})->name('login');

So I checked, the Label Value: shows the variable that I passed from the PHP file not on the VUE code.

Kind of hard to explain but you get the point. Was wondering how to bypass twig's template and use the {{ }} from vue also.

enter image description here

felipsmartins
  • 13,269
  • 4
  • 48
  • 56
Wesley Brian Lachenal
  • 4,381
  • 9
  • 48
  • 81

11 Answers11

137

Just change default delimiters for vue. Here's how:

Vue.js 1.0

Define delimiters globally (docs).

Vue.config.delimiters = ['${', '}']

Vue.js 2.0

Define delimiters for component (docs).

new Vue({
  delimiters: ['${', '}']
})

Vue.js 3.0

Define delimiters for application (docs).

Vue.createApp({
  delimiters: ['${', '}']
})
tony19
  • 125,647
  • 18
  • 229
  • 307
Yauheni Prakopchyk
  • 10,202
  • 4
  • 33
  • 37
62

In this case you can either change vue.js tag marker (if any) or use twig verbatim tag (much better in my opinion) which mark a section as raw text which shouldn't be evaluated by twig parser. i.e:

{% verbatim %}
    new Vue({

        el: '.container',
        data: {
            foo: 'Hello world.'
        }
    });
{% endverbatim %}

From the twig docs:

The verbatim tag marks sections as being raw text that should not be parsed. For example to put Twig syntax as example into a template you can use this snippet:

felipsmartins
  • 13,269
  • 4
  • 48
  • 56
  • Ohh! I saw that also but did not bother trying it, instead I tried autoescape and which did not worked. Hahaha. Now I tried that and it worked, I put that verbatim syntax between my vue " {% verbatim %} {{ foo }} {% endverbatim %} and it works! Thanks! :) – Wesley Brian Lachenal Jul 17 '15 at 16:50
  • For old twig version, you can use `raw` tag instead of `verbatim` – c0deMaster Apr 26 '23 at 10:37
17

I read in another similar question to do:

{{"{{vue.js variable here}}"}} 

to make it shorter. It works in SOME cases for me. But, thought you might like to see it anyway...

I didn't yet succeed to get it to work in all areas of my code.

TDawg
  • 833
  • 2
  • 8
  • 24
9

For Vue JS 2 (not sure about 1). You can use:

<span v-text="msg"></span>
<!-- same as -->
<span>{{msg}}</span>

As per documentation: https://v2.vuejs.org/v2/api/#v-text

tony19
  • 125,647
  • 18
  • 229
  • 307
James Burke
  • 2,229
  • 1
  • 26
  • 34
5

Just a heads up. On Vue JS 2. The way of doing this is add an object to Vue.

new Vue({
    el: '#app',
    delimiters: ['${', '}'],
}
Wesley Brian Lachenal
  • 4,381
  • 9
  • 48
  • 81
4

Instead of changing delimiters, making components less reusable or using less readable double escaping mechanisms, you can use Twig's source function.

The source function returns the content of a template without rendering it:

{{ source('template.html') }}
{{ source(some_var) }}

Example:

<!-- path/to/twig_template.html.twig -->
<script type="text/x-template" id="my-template">
    {{ source('path/to/vue-template.html') }}
</script>

<script>
    Vue.component('my-component', {
        template: '#my-template'
    });
</script>
stollr
  • 6,534
  • 4
  • 43
  • 59
2

Also, for those who don't want to change vue's delimiter, you can change Twig delimiter (using Silex php framework in this example):

$app->before(function() use ($app){
    $app['twig']->setLexer( new Twig_Lexer($app['twig'], [
        'tag_comment'   => ['[#', '#]'],
        'tag_block'     => ['[%', '%]'],
        'tag_variable'  => ['[[', ']]'],
        'interpolation' => ['#[', ']'],
    ]));
});

https://twig.symfony.com/doc/2.x/recipes.html#customizing-the-syntax

kiba
  • 1,355
  • 9
  • 7
2

The best solution is not to change either ones delimiter.

You can use the vuejs markup in twig like so

{{ mytwigvar }} {{ '{{' }} myvuevar {{ '}}' }}

This obviously is suboptimal, so redefine your twig loader to preprocess files and replace {{{ with {{ '{{' }} and }}} with {{ '}}' }} then you can write the markup as

{{ mytwigvar }} {{{ myvuevar }}}

Much nicer.

pid
  • 11,472
  • 6
  • 34
  • 63
  • 'nicer' -> that's very subjective. I don't think that's nicer, obviously you do though...still, it's good you put it in.. – zak Sep 04 '19 at 03:44
0

I'm using VueJs v2, with the syntax below:

<img id="bookCover" style="border:none;width:200px" :src="book.cover">

Where book.cover is one of the myVueInstance.$data.book fields.

Here's the docs

Matt
  • 3,617
  • 2
  • 27
  • 39
Miguel Pragier
  • 135
  • 2
  • 13
0

This is tested and working - vue js vars in twig template:

    new Vue({
       el: '#app',
       delimiter: ['{}'], // any delimiter you would like
    })
Denise Ignatova
  • 465
  • 4
  • 7
0

For me works the combination: delimiters: ['${', '}'] and ${VueVariable}

skybedy
  • 33
  • 8