简体   繁体   English

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

[英]LARAVEL + Vue.js: using blade to show whole page vue.js components in MPA, not SEO friendly

So I'm thinking about the structure for my restaurant web page which will use laravel as the back-end (routing and displaying blade views to the browser, easy auth system and sessions) and vue.js for the front-end (I have a single vue instance where I register components, this components are each one a view, a whole page, most of these pages have 2 or 3 components nested, like an image slider, to-top anchor, I use axios to fetch my API endpoints without refreshing the page plus many CRUD operations from an admin panel).所以我正在考虑我的餐厅网页的结构,它将使用 laravel 作为后端(路由和显示刀片视图到浏览器、简单的身份验证系统和会话)和前端的 vue.js(我有我在其中注册组件的单个 vue 实例,每个组件都是一个视图,一个完整的页面,这些页面中的大多数都嵌套了 2 或 3 个组件,例如图像滑块,顶部锚点,我使用 axios 来获取我的 API 端点无需刷新页面以及管理面板中的许多 CRUD 操作)。

This is how my index.blade.php view looks ( www.domain.com/ ), I have many views like posts.index.blade.php...这就是我的 index.blade.php 视图的外观( www.domain.com/ ),我有很多视图,例如 posts.index.blade.php ...

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

As you can see, I want to treat each page as a vue.component with many components nested inside of each page component).如您所见,我想将每个页面视为一个 vue.component,每个页面组件中都嵌套了许多组件)。

I have a few questions about possible complications using this structure.我有几个关于使用这种结构可能出现的并发症的问题。

When displaying views I always return a json object with all the data I want to render on blade, since each page is basically a vue.js component loaded via javascript how will I able to loop through the dishes, events and posts I fetched from the backend.显示视图时,我总是返回一个 json 对象,其中包含我想在刀片上呈现的所有数据,因为每个页面基本上都是一个通过 javascript 加载的 vue.js 组件,我将如何循环浏览从后端。 This is, I want to use the v-for directive but how can my component know of the data passed to blade?也就是说,我想使用 v-for 指令,但我的组件如何知道传递给刀片的数据? I donn't want to use axios on mounted to populate my views... that would increase drastically the number of requests send to the backend.我不想在 mount 上使用 axios 来填充我的视图……这会大大增加发送到后端的请求数量。

Since the whole page content is rendered via javascript won't this affect negatively SEO??由于整个页面内容是通过 javascript 呈现的,这不会对 SEO 产生负面影响吗? afaik search engones crawlers won't fetch the content displayed by javascript. afaik search engones 爬虫不会获取 javascript 显示的内容。

Is this a good practice, is this the best way to handle laravel + vue.js non-SPA?这是一个好习惯吗,这是处理 laravel + vue.js 非 SPA 的最佳方式吗? Is this a good abstraction of front-end and back-end?这是前端和后端的一个很好的抽象吗?

How I will handle auth is by doing axios requests to laravel login endpoints.我将如何处理身份验证是通过对 laravel 登录端点执行 axios 请求。

For passing data to your vue component, you can use props .要将数据传递给您的 vue 组件,您可以使用props

IndexController.php索引控制器.php

    ...
    $events = [
        ['id' => 111, 'foo' => 'bar'],
        ['id' => 123, 'foo' => 'bar']
    ];
    
    return view('index')->with(compact('events')); // send events to blade
}

index.blade.php index.blade.php

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

PageIndexComponent.vue PageIndexComponent.vue

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

Here you can do your v-for loop with parsedEvents .在这里,您可以使用parsedEvents执行v-for循环。


For SEO, you can edit your resources/views/layouts/master.blade.php :对于 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">
        ...

And in each view you can either hardcode your title, description etc or send it from your Controllers:在每个视图中,您可以硬编码您的标题、描述等,也可以从控制器发送:

@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

Your app structure wants vue.js files and id of the element where it can render components:您的应用程序结构需要 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>

Remember!记住! You have to include vue.js files where you want to use vue in laravel application您必须在 laravel 应用程序中包含要使用 vue 的 vue.js 文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM