LARAVEL + Vue.js:使用刀片在 MPA 中显示整个页面的 vue.js 组件,对 SEO 不友好

Posted

技术标签:

【中文标题】LARAVEL + Vue.js:使用刀片在 MPA 中显示整个页面的 vue.js 组件,对 SEO 不友好【英文标题】:LARAVEL + Vue.js: using blade to show whole page vue.js components in MPA, not SEO friendly 【发布时间】:2019-02-19 11:23:42 【问题描述】:

所以我正在考虑我的餐厅网页的结构,它将使用 laravel 作为后端(路由和显示刀片视图到浏览器、简单的身份验证系统和会话)和前端的 vue.js (我有一个注册组件的vue实例,这个组件每个都是一个视图,一个完整的页面,这些页面中的大多数都有2或3个嵌套的组件,比如图像滑块,顶部锚点,我使用axios来获取我的 API 端点没有刷新页面以及管理面板中的许多 CRUD 操作)。

这就是我的 index.blade.php 视图的外观 ( www.domain.com/ ),我有很多视图,例如 posts.index.blade.php...

@extends('layouts.master')
@section('content')
    <page-index></page-index)
@endsection

如您所见,我想将每个页面视为一个 vue.component,每个页面组件内部都嵌套了许多组件。

我有几个关于使用这种结构可能出现的并发症的问题。

当显示视图时,我总是返回一个 json 对象,其中包含我想在刀片上呈现的所有数据,因为每个页面基本上都是一个通过 javascript 加载的 vue.js 组件,我将如何循环浏览菜肴、事件和帖子我从后端获取。也就是说,我想使用 v-for 指令,但我的组件如何知道传递给刀片的数据?我不想在 mount 上使用 axios 来填充我的视图......这会大大增加发送到后端的请求数量。

由于整个页面内容是通过 javascript 呈现的,这不会对 SEO 产生负面影响吗? afaik search engones 爬虫不会获取 javascript 显示的内容。

这是一个好的做法,这是处理 laravel + vue.js 非 SPA 的最佳方式吗?这是对前端和后端的一个很好的抽象吗?

我将如何处理身份验证是通过向 laravel 登录端点发出 axios 请求。

【问题讨论】:

【参考方案1】:

要将数据传递给你的 vue 组件,你可以使用props。

IndexController.php

    ...
    $events = [
        ['id' => 111, 'foo' => 'bar'],
        ['id' => 123, 'foo' => 'bar']
    ];

    return view('index')->with(compact('events')); // send events to blade

index.blade.php

@extends('layouts.master')
@section('content')
    <page-index events=" json_encode($events) "></page-index> // send events to vue
@endsection

PageIndexComponent.vue

<script>
    export default 
        props: ['events'], // get events from here
        mounted() 
            parsedEvents = JSON.parse(this.events);
        
    
</script>

在这里,您可以使用parsedEvents 执行您的v-for 循环。


对于 SEO,您可以编辑您的 resources/views/layouts/master.blade.php

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content=" csrf_token() ">
        <meta name="title" content="@hasSection('title')@yield('title')@else config('app.name') @endif">
        <meta name="description" content="@hasSection('description')@yield('description')@else config('app.name') @endif">
        <meta property="og:title" content="@hasSection('title')@yield('title')@else config('app.name') @endif">
        <meta property="og:description" content="@hasSection('description')@yield('description')@else config('app.name') @endif">
        <meta property="og:image" content="@hasSection('image')@yield('image')@else asset('/images/avatar.jpg') @endif">
        <meta property="og:type" content="@yield('type')">
        <meta property="og:url" content=" url()->current() ">
        <meta property="og:locale" content="en_US">
        ...

在每个视图中,您可以硬编码您的标题、描述等,也可以从您的控制器发送:

@extends('layouts.master')

@section('title', 'Events') // or something like $page_title received from controller
@section('description', 'All Events') // or $page_desc sent from controller
@section('image', 'http://imgurl.com/123.png') // etc, etc
@section('type', 'article')

@section('content')
    <page-index events=" json_encode($events) "></page-index)
@endsection

【讨论】:

很好的解释!但是从带有 JSON 的 db 解析到 Vue 组件的数据,对 SEO 友好吗? Google 会抓取这些信息吗? 有趣的问题!但我不知道机器人看到了什么。如果我不得不猜测我会说,可能不会。当我开始在我的联系表单中使用 vuejs 时,我不再让这些垃圾邮件机器人填满乱码。所以我会说机器人可能会阅读&lt;my-component events="" /&gt;而不是实际的html。我可能错了,大拇指吮吸。【参考方案2】:

您的应用结构需要 vue.js 文件和可以渲染组件的元素的 id:

<html>
    ...
   <head>...</head>
<body>
    @extends('layouts.master')
    @section('content')
     <div id="app">   //vue will read this id and render components
        <page-index></page-index>
     </div>
    @endsection

   <script src="/js/app.js"></scrip> 
   // this is where webpack usually place compiled js files. It will run vue.on element having id=app.

 </body>

记住!你必须在 laravel 应用程序中包含你想要使用 vue 的 vue.js 文件

【讨论】:

你有没有找到任何解决方案。我必须面对同样的问题。

以上是关于LARAVEL + Vue.js:使用刀片在 MPA 中显示整个页面的 vue.js 组件,对 SEO 不友好的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.5 和 Vue.js 刀片测试

Laravel、刀片、vue.js 和 @if (@ )

来自 Vue.js 的组件未加载到 Laravel 刀片中

为啥 vue js 组件没有显示在 laravel 刀片中?

在 laravel 刀片视图中显示 vue js 模板

laravel 刀片模板中的 Vue.js v-for 循环