Twig 和 Vue.js 的模板冲突

Posted

技术标签:

【中文标题】Twig 和 Vue.js 的模板冲突【英文标题】:Conflict on Template of Twig and Vue.js 【发布时间】:2015-10-07 10:58:49 【问题描述】:

我正在使用 Slim 2 做一个程序,它使用 Twig 作为我的模板引擎。所以它在 php 文件中使用语法 foo 。另一方面,我使用的是 vue.js,它也使用了 bar

例如

我要做的是双向绑定,下面是我的html代码。

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

这是我的 vue js 代码。

new Vue(

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

所以 Hello world 应该在 Label Value 中。

输出如下图。

它不起作用,可能系统认为它是一个树枝变量。所以我通过在视图中传递变量来检查。

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

所以我检查了,标签值:显示了我从 PHP 文件而不是 VUE 代码上传递的变量。

有点难以解释,但你明白了。想知道如何绕过 twig 的模板并使用来自 vue 的

【问题讨论】:

【参考方案1】:

只需更改 vue 的默认分隔符。方法如下:

Vue.js 1.0

全局定义分隔符 (docs)。

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

Vue.js 2.0

为组件定义分隔符 (docs)。

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

Vue.js 3.0

为应用程序定义分隔符 (docs)。

Vue.createApp(
  delimiters: ['$', '']
)

【讨论】:

【参考方案2】:

在这种情况下,您可以更改 vue.js 标记标记(如果有)或使用 twig 逐字标记(在我看来要好得多),它将一个部分标记为不应由 twig 解析器评估的原始文本。即:

% verbatim %
    new Vue(

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

来自 twig 文档:

verbatim 标记将部分标记为不应包含的原始文本 解析。例如,将 Twig 语法作为示例放入模板中 可以用这个sn-p:

Verbatim tag

【讨论】:

哦!我也看到了,但没有费心尝试,而是尝试了自动转义,但没有奏效。哈哈哈。现在我尝试了它并且它起作用了,我将逐字语法放在我的 vue " % verbatim % foo % endverbatim % 和它的工作原理之间!谢谢!:)【参考方案3】:

我阅读了另一个类似的问题:

"vue.js variable here" 

使其更短。它适用于我的某些情况。但是,我想你还是会喜欢看的……

我还没有成功地让它在我的代码的所有领域工作。

【讨论】:

你好,我会试试这个,如果可行,我会告诉你。 :) 以前来自 felipsmartins 的答案更好......它适用于所有情况。我发送的上述内容似乎用途有限......无论如何我的测试显示。 短变量的救星,最接近 laravel Blade 的 @ variable 转义。介意分享一下您的解决方案到底哪里不起作用?【参考方案4】:

对于 Vue JS 2(不确定 1)。您可以使用:

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

根据文档:https://vuejs.org/v2/api/#v-text

【讨论】:

【参考方案5】:

只是提个醒。在 Vue JS 2 上。这样做的方法是向 Vue 添加一个对象。

new Vue(
    el: '#app',
    delimiters: ['$', ''],

【讨论】:

【参考方案6】:

您可以使用 Twig 的 source 函数,而不是更改分隔符、降低组件的可重用性或使用可读性较差的双重转义机制。

源函数返回模板的内容而不渲染它:

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

示例:

<!-- 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>

【讨论】:

投反对票的原因是什么?请在投票时发表评论! 现在好多了。不知道为什么投反对票,但我只是弥补了这一点......【参考方案7】:

另外,不想修改vue的分隔符的,可以修改Twig分隔符(本例使用Silex php框架):

$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

【讨论】:

【参考方案8】:

最好的解决方案是不要更改任何一个分隔符。

你可以像这样在 twig 中使用 vuejs 标记

 mytwigvar   ''  myvuevar  '' 

这显然不是最理想的,所以重新定义你的树枝加载器来预处理文件并将替换为 '' 替换为 '' 然后你可以将标记写为

 mytwigvar   myvuevar 

好多了。

【讨论】:

'更好' -> 这是非常主观的。我不认为这更好,但显然你这样做了......不过,你把它放进去很好......【参考方案9】:

这是经过测试和工作的 - 树枝模板中的 vue js vars:

    new Vue(
       el: '#app',
       delimiter: [''], // any delimiter you would like
    )

【讨论】:

【参考方案10】:

我使用的是 VueJs v2,语法如下:

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

其中 book.cover 是 myVueInstance.$data.book 字段之一。

Here's the docs

【讨论】:

以上是关于Twig 和 Vue.js 的模板冲突的主要内容,如果未能解决你的问题,请参考以下文章

vue.js与后台模板引擎“双花括号”冲突时的解决办法

在 Golang 的 HTML 模板中使用 Vue.js [重复]

构建自己的PHP框架(Twig模板引擎)

如何在 Twig 中将变量从父模板传递到子模板?

从包含的 Twig 模板中干净地添加 JS 和 CSS

Twig 模板引擎不读取对象属性