如何在Shopware(Symfony Twig)中将带翻译字符串的对象传递给Vue组件
问题原因
- HTML自定义属性未用双引号包裹,序列化后的JSON特殊字符会破坏属性结构,导致取值不完整
- Twig的
json_encode输出默认会被HTML转义,未加raw过滤器会导致输出的JSON为不可解析的转义格式 - Shopware的
trans过滤器在对应snippet不存在时会返回空字符串,需先确认example.header这个snippet配置真实存在 - 从DOM属性拿到的是字符串格式的JSON,未反序列化为JS对象,后续使用也会出现异常
可行实现方案
第一步:修正Twig模板代码
{% set snippets = { header: example.header|trans } %} {# 属性加双引号包裹,json_encode添加转义参数,再加raw过滤器禁止转义 #} <div id="app" data-snippets="{{ snippets|json_encode(constant('JSON_HEX_QUOT') b-or constant('JSON_HEX_APOS'))|raw }}"> <demo></demo> </div> <script> new Vue({ components: { demo: Component } }).$mount('#app') </script>
参数说明:JSON_HEX_QUOT和JSON_HEX_APOS会把JSON里的双引号、单引号转成十六进制编码,避免和HTML属性的引号冲突,raw过滤器禁止Twig对输出内容做HTML转义,自定义属性使用data-前缀符合HTML规范。
第二步:修正Vue组件代码
data() { let snippetStr = document.getElementById('app').getAttribute('data-snippets') return { // 把字符串格式的JSON反序列化为JS对象 snippet: snippetStr ? JSON.parse(snippetStr) : {}, } }, mounted() { console.log(this.snippet); }
替代实现方案(更简单,无需读取DOM属性)
直接把翻译对象挂载到全局变量,避免HTML属性转义问题:
{% set snippets = { header: example.header|trans } %} <div id="app"> <demo></demo> </div> <script> // 直接输出JSON为JS全局对象 window.appSnippets = {{ snippets|json_encode()|raw }}; new Vue({ components: { demo: Component } }).$mount('#app') </script>
Vue组件内直接读取全局变量即可:
data() { return { snippet: window.appSnippets || {}, } }, mounted() { console.log(this.snippet); }
如果修改后依然返回空值,可先在Twig模板中单独输出{{ example.header|trans }}确认snippet本身配置正确。
内容的提问来源于stack exchange,提问作者willoid
相关产品推荐
相关产品推荐

