如何解决Vue元没有得到更新 澄清额外
当我访问我的内部页面时,vue-Meta
不会被新页面值更新。
代码
app.js
import VueMeta from 'vue-Meta'
Vue.use(VueMeta,{
refreshOnceOnNavigation: true
})
App.vue
(主要组件)
export default {
MetaInfo() {
return {
title: process.env.MIX_APP_NAME,titleTemplate: `%s | ${process.env.MIX_APP_NAME}`,Meta: [
{ name: "robots",content: "index,follow" },{
vmid: "description",name: "description",content:
"..........",},// and many more....
],}
}
}
post.vue
(内部组件)
export default {
name: "singePost",data() {
return {
post: "",};
},MetaInfo() {
return {
title: this.post.name,// not receiving data
Meta: [
{
vmid: "description",content: this.post.Metas[0].description,// not receiving data
},// others......
],}
},mounted() {
this.getPost();
},methods: {
getPost() {
axios
.get("/api/articles/" + this.$route.params.slug,{
headers: {
Authorization: localStorage.getItem("access_token"),})
.then((response) => {
this.post = response.data.data;
})
.catch((error) => {
//....
});
},
有什么想法吗?
更新
当我发布这个问题时,它是关于没有更新然后在做了一些研究并玩弄我的代码之后我意识到我的 vue-Meta 得到了更新,但是,晚了 并导致社交网站和 SEO 检查器无法正确检索我的 URL。
澄清
My full Meta tags code
MetaInfo() {
return {
title: this.post.name,Meta: [
{
vmid: "keyword",name: "keyword",content: this.post.Metas[0].tags,// Open Graph / Facebook
{ vmid: "og:type",name: "og:type",content: "website" },{
vmid: "og:url",name: "og:url",content: process.env.MIX_APP_URL + this.$router.currentRoute.fullPath,{
vmid: "og:site_name",name: "og:site_name",content: `"${process.env.MIX_APP_NAME}"`,{
vmid: "og:title",name: "og:title",content: this.post.name,{
vmid: "og:description",name: "og:description",{
vmid: "og:image",name: "og:image",content: this.post.imagebig,// Twitter
{
vmid: "twitter:card",name: "twitter:card",content: "summary",{
vmid: "twitter:author",name: "twitter:author",content: "@xxxxxx",{
vmid: "twitter:site",name: "twitter:site",{
vmid: "twitter:creator",name: "twitter:creator",{
vmid: "twitter:url",name: "twitter:url",{
vmid: "twitter:title",name: "twitter:title",{
vmid: "twitter:description",name: "twitter:description",{
vmid: "twitter:image",name: "twitter:image",],
额外
-
最近我读了一篇文章,因为基于 JavaScript 的 vue-Meta(一般是 Vue)加载社交媒体爬虫不会缓存它们,因此当我在 FB 或 Twitter 上分享它们时,不可能看到我的链接详细信息等
-
建议的解决方案是使用 Nuxt 并返回元数据服务器端。
问题
- 我不确定上面的 #1 有多少是正确的,但有可能
- 我的应用程序一般不使用 Nuxt,但我只是安装了它的 npm 包,所以它可能值得一试(正如我提到的,我从未使用过 Nuxt,因此如果您的帮助解决方案就是这种情况,我将不胜感激在你的回答中加入一些额外的细节)。
解决方法
Vue 本身是客户端 JS 框架。当您构建时,您的 index.html
没有任何内容 - 只有在执行时生成内容的 JS。这同样适用于 VueMeta。问题是,当您共享链接(FB、Twitter 等)时,他们会使用自己的机器人(本质上是爬虫)下载链接页面并分析内容而无需在内部执行任何 JS - 所以是的,他们不会没有看到任何由 VueMeta 生成的元数据...
唯一的解决方案是在不执行JS的情况下提供包含所有重要信息的完全(或部分)预渲染页面
这样做的一种方法是使用 Vue server side rendering - 你是对的,像 Nuxt 这样的框架正是使用它。
一般有两种口味:
SSR - 页面在客户端(或机器人)请求时呈现。大多数情况下它需要运行 Node 服务器(因为 Vue SSR 是在 JS 中实现的)。最突出的例子是 Nuxt.js
SSG - 服务器端生成。页面在构建时生成,包括所有 HTML。当加载到浏览器服务器时返回 HTML + 所有的 JS/CSS,但是当它加载时它是相同的 Vue SPA。您不需要 Node 服务器,因此您可以在 CDN 或任何静态托管服务(如 Netlify)上托管。 Vue 世界中的例子有 Gridsome、VuePress、Nuxt 也可以做到...
注意:还有其他方法,例如使用 headless chrome/puppeteer 或 https://prerender.io/ 之类的服务
Nuxt
如前所述,Nuxt 很棒,但对您的应用程序的结构(基于文件的路由)、如何获取数据等非常有意见。因此,切换到 Nuxt 可能意味着完全重写应用程序。最重要的是,它需要运行 NODE 服务器,这会产生其自身的后果(托管)。
但是在我看来您已经在使用服务器 - Laravel。所以你最好的选择可能是直接在 Laravel 中实现你的元渲染。
更新:似乎可以做 Vue SSR directly in Laravel
,你的假设是正确的。不久前,我也花了相当多的时间试图找到解决这个问题的方法。这是我在一天结束时想到的:
- 继续使用
vue-meta
,对于那些运行 JavaScript 的爬虫(它没有害处,对吧?)。 - 实现服务器端解决方案(使用 Laravel 包)。
选项 1 应该很清楚,因为您已经有了类似的实现。
对于选项 2,这是我的方法:
-
我为我的 Laravel 应用程序选择了 this 包。它易于安装和注册。我敢肯定,有许多适用于 Laravel 或其他框架和语言的包可以做同样的事情。
-
我在捕获所有前端路由请求的路由文件(
web.php
,如果您使用 Laravel)的末尾添加了此路由:
Route::get('/{any}','IndexController@index')->where('any','.*');
在 IndexController
中,我首先检查请求是否来自爬虫。如果是这样,我会应用相关的元标记。这是一个一瞥:
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use Butschster\Head\Facades\Meta;
use Butschster\Head\Packages\Entities\OpenGraphPackage;
class IndexController extends Controller
{
const CRAWLERS = [
'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)','Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML,like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 (compatible; AdsBot-Google-Mobile; +http://www.google.com/mobile/adsbot.html)','Mozilla/5.0 AppleWebKit/537.36 (KHTML,like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Safari/537.36','Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)','Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML,like Gecko) BingPreview/1.0b','Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML,like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)','Googlebot-Image/1.0','Mediapartners-Google','facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)','facebookexternalhit/1.1','Twitterbot/1.0','TelegramBot (like TwitterBot)',];
public function index()
{
if ($this->isACrawler()) {
$this->applyMetaTags();
return view('layouts.crawler');
}
return view('layouts.index');
}
public function isACrawler()
{
if (in_array(request()->userAgent(),self::CRAWLERS)) {
return true;
}
return false;
}
private function applyMetaTags()
{
// Here you can check the request and apply the tags accordingly
// e.g.
// preg_match("/articles\/[0-9]+/i",request()->path(),$url)
// preg_match("/[0-9]+/i",$url[0],$id);
// $article = Article::find($id);
//
// Meta::prependTitle($article->name)
// ->addMeta('description',['content' => $article->description]);
//
// $og = new OpenGraphPackage('some_name');
//
// $og->setType('Website')
// ->setSiteName('Your website')
// ->setTitle($article->name)
// ->setUrl(request()->fullUrl())
// ->setDescription($article->description);
//
// if ($article->picture) {
// $og->addImage(asset($article->picture));
// }
//
// Meta::registerPackage($og);
}
}
最后我创建了一个只有 head
部分的模板(这是爬虫唯一关心的 html 部分)并应用元标记:
<!DOCTYPE html>
<html lang="{{ str_replace('_','-',app()->getLocale()) }}">
<head>
@meta_tags
<link rel="shortcut icon" href="{{ asset('favicon.ico') }}">
</head>
</html>
注意事项:
- 您需要为每个请求自定义元标记
- 您需要维护一个爬虫列表
好处:
- 它很简单,不需要对代码进行太多更改
- 它向爬虫返回一个快速且轻量级的 HTML
- 您对后端拥有完全控制权,只需稍作调整即可实施可维护的解决方案
希望这有帮助!如果有不清楚的地方,请告诉我。
,问题
我不确定上面的 #1 有多少是正确的,但有可能我的应用 通常不使用 Nuxt 但我只是安装了它的 npm 包所以 可能值得一试(正如我提到的,我从未使用过 Nuxt,所以如果 这就是您的帮助解决方案的情况,如果您愿意,我将不胜感激 在你的回答中加入一些额外的细节)。
对您的问题的简短回答:您不能动态更改 vue 元标记,因为这需要服务器端渲染 (nuxt)
,您需要实现服务器端渲染来处理元标记。 因为几乎所有的爬虫都不支持javascript进程。
这是 PHP 的示例 - Laravel。
我们知道 vue.js 是一个单页应用程序。所以每次从一个根页面渲染。
所以对于laravel,我按原样配置了路由,每次返回带有标签数组的索引页面并在视图中呈现该页面(索引页面)
- Laravel 路由
<?php
use Illuminate\Support\Facades\Route;
Route::get('users/{id}','UserController@show');
Route::get('posts/{id}',function () {
$tags = [
'og:app_id' => '4549589748545','og:image' => 'image.jpg','og:description' => 'Testing'
];
return view('index',compact('tags'));
});
Route::get('/{any}',function () {
$tags = [
'description' => 'Testing','keywords' => 'Testing,Hello world',];
return view('index',compact('tags'));
})->where('any','.*');
?>
- 控制器
<?php
use App\Http\Controllers\Controller;
use App\Models\User;
class UserController extends Controller
{
public function show(User $user)
{
$tags = [
'og:app_id' => '4549589748545','og:description' => 'Testing'
];
return view('index',compact('tags'));
}
}
?>
- 索引页
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
@foreach($tags as $key => $value)
<meta property="{{$key}}" content="{{$value}}">
@endforeach
</head>
<body id="app">
<script type="text/javascript" src="{{ asset('js/app.js') }}"></script>
</body>
</html>
你可以配置 webpack 来注入静态标签
vue-cli 3 抽象了 webpack 配置文件(在运行时生成),所以为了配置它,你需要添加一个 vue.config.js 到你的项目根目录(如果你没有,通常你赢了) 't)
例如:
// vue.config.js
module.exports = {
configureWebpack: {
output: {
publicPath: '/static/'
},plugins: [
new HtmlWebpackPlugin(),new HtmlWebpackTagsPlugin(
{tags: ['a.js','b.css'],append: true },{metas: [{
path: 'asset/path',attributes: {
name: 'the-meta-name'
}}]
})
]
}
}
(使用 https://github.com/jharris4/html-webpack-tags-plugin 请参阅链接中的示例以了解其具体输出)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。