vue组件html元素渲染

Posted

技术标签:

【中文标题】vue组件html元素渲染【英文标题】:vue component html elemnet Rendering 【发布时间】:2019-05-04 20:16:18 【问题描述】:

我正在使用 Laravel 5.6 版和 vue.js 2.0 版开发一个多页 Web 应用程序 (MPA)。

我正在使用多个 vue 组件,例如Demo.vue 并在 php Blade 文件中使用该组件。

问题是当我尝试查看页面视图源 (ctrl+u) 时,它仅显示 php Blade 文件中使用的 html 标签,但不显示 vue 组件的 HTML 元素。

我希望 Vue 组件 HTML 元素也显示在页面视图源中,因为我的 google 抓取主要依赖于使用的 vue 组件。你能帮我解决这个问题吗?

同时附上页面源截图和示例代码sn-p。

Demo.vue 文件代码

<template>
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-md-8">
                    <div class="card card-default">
                        <div class="card-header">Example Component</div>

                        <div class="card-body">
                            I'm an example component.
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </template>

<script>
    export default 
        mounted() 
            console.log('Component mounted.')
        
    
</script>                                                                                       

App.js

require('./bootstrap');
window.Vue = require('vue');
window.axios = require('axios');
import VModal from 'vue-js-modal';

Vue.use(VModal);
Vue.component('demo-component', require('./components/Demo.vue'));
const app = new Vue(
    el: '#app',

);

Layout.blade.php

<!DOCTYPE html>
    <html lang=" app()->getLocale() ">

    <head>
          <meta charset="UTF-8">
                <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <form method="POST" action="path_to_action">
                <meta name="csrf-token" content=" csrf_token() ">
                </form>
          <!--<link href="css/style.css" rel="stylesheet">-->
          <link href="https://fonts.googleapis.com/css?family=Roboto:300,500,700,900" rel="stylesheet">
                 <link href="/css/app.css" rel="stylesheet" type="text/css">
    </head>
    <body id="body">

        <div class="content" id="app">
         <demo-component></demo-component>
        </div>



        <script type="text/javascript" src="/js/app.js"></script>


    </body>
</html>

即我们希望在视图源中呈现 HTML 代码。

我们甚至尝试查看关于 s-s-r 的各种文章,但这些示例使用静态内容显示,而我们的数据是来自数据库的动态数据,并且是一个多页面应用程序。

例如我们尝试了以下方法:-

https://vuejsdevelopers.com/2017/11/06/vue-js-laravel-server-side-rendering/

以上文章仅针对静态数据显示...

谢谢, 查理兹

【问题讨论】:

您是否转译了App.js 文件?您的浏览器控制台中是否有任何错误? 为什么要实现这个?在视图源中显示渲染的 HTML 有什么好处吗? 【参考方案1】:

这是您选择使用 Vue 等反应式框架时面临的常见问题。问题是 HTML 本身并没有在初始页面加载时呈现,而是在事后由 javascript 填充,然后呈现给用户。您无法解决 Vue 组件的这个特殊问题,而且由于您使用的是动态数据,因此您无法缓存 HTML 本身。

然而,我过去成功使用的一种有趣的方法是在页面加载时实际呈现“占位符”HTML,它只是省略了动态数据,然后使用 v-show 或 v-if 方法来切换占位符数据加载完成后的 HTML 和动态 HTML 数据。如果你不使用过渡,这可能会导致一些闪烁,但如果你真的想让 google 抓取那个 HTML,并且你真的需要使用 Vue,那么这是一个很好的解决方案。一个简化的例子是这样的:

<div v-show="loaded">
    <example-component></example-component>
</div>
<div id="placeholder">
    <div>
        Hello, Google Bot!
    </div>
</div>

然后,当您的组件被挂载时,您将“已加载”变量的值更改为 true,并使用发射器将其传递给父级,同时还使用 javascript 隐藏原始 div,从而用您的 Vue 替换占位符 HTML生成的 HTML。 Google 将能够看到占位符中的任何内容,并且一旦加载,您仍然可以获得动态内容。这不是最漂亮的答案,并且需要使用一些非常非反应性的做法来实现结果,但请注意,这只是试图为您提供可能适用于您的特定用例的答案。

在实现此方法时,您可能需要考虑在实际调用占位符 HTML 的 Vue 组件本身中使用包含,这样您就不会重复自己,并且您只是在一个源位置更新静态 HTML。如果您需要,我可以提供更多帮助。

【讨论】:

考虑在实际调用占位符 HTML 的 Vue 组件本身中使用包含我没有得到(实际上如何实现上面的句子)你想说的话。你能解释一下很深吗? 这是我回答中最不重要的部分,只是提醒您使用 DRY 原则并尽可能重用代码。

以上是关于vue组件html元素渲染的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs - 组件式开发

Vue的一些基本指令

我可以(并且我应该)断言组件使用 Enzyme 的 shallow() 渲染了哪些 HTML 元素吗?

vue中的组件

Vue js 用 html 内容渲染文本

vue中$refs的使用记录