Quasar s-s-r:使用引导文件将 HTML 内容注入 index.html

Posted

技术标签:

【中文标题】Quasar s-s-r:使用引导文件将 HTML 内容注入 index.html【英文标题】:Quasar s-s-r: Inject HTML content into index.html using boot file 【发布时间】:2020-05-03 11:44:39 【问题描述】:

我有一个 Quasar s-s-r 应用程序,当页面在服务器上呈现时,我需要在 <div id="q-app"> 元素周围动态注入 html 内容(即自定义页眉和页脚内容)。有问题的 HTML 内容将从服务器上存储的其他 sn-p 文件中提取。

我尝试从引导文件中将内容添加到s-s-rContext,然后使用 标签将其插入到 index.template.html 中,但这会导致 HTML 转义输出:

在whitelabeltemplate.js(启动文件)中:

export default ( app, s-s-rContext ) => 
    s-s-rContext.templateHeaderHTML = '<div>This is the header</div>'

在 index.template.html 中:

<body>
    <% if (htmlWebpackPlugin.options.ctx.mode.s-s-r)  %> templateHeaderHTML <%  %>
    <!-- DO NOT touch the following DIV -->
    <div id="q-app"></div>
</body>

结果:

<body class="desktop no-touch body--light" >
    &lt;div&gt;This is the header&lt;/div&gt;
    <!-- DO NOT touch the following DIV -->
    <div id="q-app" ...
        ...
</body>

是否有注入此内容的替代方法以避免转义?

【问题讨论】:

也许 Meta 插件会有所帮助? quasar.dev/quasar-plugins/meta 谢谢...我刚才根据你的建议看了一眼。最终可能会将其用于其他用途,但据我所知,我认为它不能提供足够的灵活性来解决这一特殊要求。 你用的是哪个版本的vue?在 v1 中,您可以使用 unsafeSring ,但在 v2 中已将其删除。 v2.但是,无论如何,Vue 实际上超出了这里发生的事情的范围 - 请参阅引导文件部分here 和 here 【参考方案1】:

是的,有,v-html 属性正是为了这个目的:

<body>
    <div id="q-app">
        <% if (htmlWebpackPlugin.options.ctx.mode.s-s-r)  %>
            <div v-html="templateHeaderHTML"></div>
        <%  %>
        <!-- DO NOT touch the following DIV -->
        <div id="content"></div>
    </div>
</body>

你需要一个标签才能使用v-html,所以我建议从实际内容中剥离包装器div来注入。

编辑

由于我们不允许在 q-app div 中工作,让我们恢复初始 HTML,稍作改动:

<body onload="unescapeHTML();">
    <script type="text/javascript">
    function htmlDecode(input)
        var e = document.createElement('textarea');
        e.innerHTML = input;
        // handle case of empty input
        return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
    

    function unescapeHTML() 
        //Let's select the divs where we want this unescape to occur
        //At this point there is a single element with this property, but
        //let's support plurality
        var divs = document.querySelectorAll("body > div:nth-child(1)");
        for (let div of divs) div.innerHTML = htmlDecode(div.innerHTML);
    
    </script>
    <% if (htmlWebpackPlugin.options.ctx.mode.s-s-r)  %> templateHeaderHTML <%  %>
    <!-- DO NOT touch the following DIV -->
    <div id="q-app"></div>
</body>

灵感来自这里:Unescape HTML entities in Javascript?

【讨论】:

@JohnRix 你可以制作一个包裹在页眉、内容和页脚周围的 div。如果你这样做,那么你将能够使用 v-html 作为页眉、内容和页脚,因为在这种情况下,它们将是该模板的子标签。 据我了解,Quasar 将 Vue 应用程序应用于#q-app 元素。因此,除此之外的任何内容都超出了 Vue 的范围,因此不会在那里处理 v-html 属性。不久前,我已经完全按照您上面的示例进行了尝试,但我得到的只是&lt;div v-html="templateHeaderHTML"&gt;&lt;/div&gt; @JohnRix 理解并相应地编辑了答案。如果 q-app 包裹在页眉、内容和页脚周围,那么它应该可以工作。 很遗憾,我不能这样做,根据上面包含在 Quasar 生成的模板文件中的注释:&lt;!-- DO NOT touch the following DIV --&gt; @JohnRix 所以你只处理页眉和页脚,不允许触摸实际内容?

以上是关于Quasar s-s-r:使用引导文件将 HTML 内容注入 index.html的主要内容,如果未能解决你的问题,请参考以下文章

如何将 @vue/apollo-composable 添加到 Quasar 框架

如何将 Quasar 2 与 AWS Amplify 结合使用?

Quasar 框架上传器与 axios

如何将我的 JSON 数据文件的结果映射到 quasar 表中?

Next Js API:使用 s-s-r 反应页面的响应

Vue.js 单文件组件中的 Mapbox-gl (Quasar-Framework)