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 时,我不再让这些垃圾邮件机器人填满乱码。所以我会说机器人可能会阅读<my-component events="" />
而不是实际的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 不友好的主要内容,如果未能解决你的问题,请参考以下文章