Conflict on Template of Twig and Vue.js
JavascriptSymfonyTwigvue.jsJavascript Problem Overview
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.
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.
Javascript Solutions
Solution 1 - Javascript
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: ['${', '}']
})
Solution 2 - Javascript
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:
Solution 3 - Javascript
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.
Solution 4 - Javascript
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://vuejs.org/v2/api/#v-text
Solution 5 - Javascript
Just a heads up. On Vue JS 2. The way of doing this is add an object to Vue.
new Vue({
el: '#app',
delimiters: ['${', '}'],
}
Solution 6 - Javascript
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>
Solution 7 - Javascript
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
Solution 8 - Javascript
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.
Solution 9 - Javascript
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.
Solution 10 - Javascript
This is tested and working - vue js vars in twig template:
new Vue({
el: '#app',
delimiter: ['{}'], // any delimiter you would like
})
Solution 11 - Javascript
For me works the combination: delimiters: ['${', '}'] and ${VueVariable}