vue element 根据文章内容动态修改网页标题Title、描述Description,关键字Keywords等
- by chenxue4076
- 4 years ago
话不多说,直接上解决方法,先说下 关键的目录结构
website:
|-public
| |–index.html
|-src
| |-components
| | |-CommonFooter.vue
| |-router
| | |-index.ts
| | -views
| | |-Blog
| | | |-Detail.vue
| |-App.vue
| |-main.ts
1.在index.html中配置好相关元素,如下所示:author,description,keywords 和title
<title>风火家人</title>
<meta name="author" content="chenxue4076@163.com" />
<meta name="description" content="技术总结,个人开发日记" />
<meta name="keywords" content="技术总结,服务器,开发,PHP,Python,AiStudio,CMS,MySql" />
2.我并没有直接在App.vue中直接添加自定义标签,而是引用了compoents下的CommonFooter.vue, 按道理在App.vue中直接使用应该是没有问题的, 只能让读者自己去尝试看下,下面是我在App.vue应用CommonFooter.vue的代码:
<template>
<el-container id="app" direction="vertical">
/*省略掉了很多内容*/
<CommonFooter />
</el-container>
</template>
<script>
import CommonFooter from "@/components/CommonFooter.vue";
export default {
/*省略掉了很多内容*/
components: {
CommonFooter
}
};
</script>
3.CommonFooter.vue 配置自定义标签如下。其目的是为首页或列表页展示标题、描述、关键字等使用。后面使用 dataset中的 title,description等获取内容。
<template>
<el-footer class="page-footer" height="auto">
/*省略掉了很多内容*/
<div v-web-title :data-title="WebTitle" />
<div v-web-description :data-description="WebDescription" />
<div v-web-keywords :data-keywords="WebKeywords" />
<div v-web-author :data-author="WebAuthor" />
</el-footer>
</template>
<script lang="ts">
import {
Component,
Vue
} from "vue-property-decorator";
@Component
export default class CommonFooter extends Vue {
WebTitle: string = "";
WebDescription: string = "";
WebKeywords: string = "";
WebAuthor: string = "";
}
</script>
4.给路由文件添加 title,description,keywords,author等meta信息,作为通用的描述信息meta。
const routes = [
{
path: "/",
component: () => import("../views/BookNote/Index.vue"),
meta: {
title: "书摘" ,
description: "记录看过的那些书",
keywords: "文摘,经典语句,名人名言,读书笔记",
author: "chenxue4076@163.com"
},
children: [
{
path: "",
name: "booknote",
component: () => import("../views/BookNote/List.vue")
}
]
},
{
path: "/blog",
component: () => import("../views/Blog/Index.vue"),
meta: {
title: "程序开发经验",
description: "开发经验总结,做过的开发重点记录",
keywords:
"CentOS,CodeIgniter,Docker,Git,Go,Golang,MySql,PHPOffice,SSL,Wechat,算法,加密解密,Nginx,PHP,服务器",
author: "chenxue4076@163.com"
},
children: [
{
path: "",
name: "blog",
component: () => import("../views/Blog/List.vue")
},
{
path: "index",
name: "blog_index",
component: () => import("../views/Blog/List.vue")
},
{
path: ":year/:month/:slug",
name: "blog_detail",
component: () => import("../views/Blog/Detail.vue")
}
]
},
5.因为是 CommonFooter.vue是针对列表或一些不需要根据详细内容配置标题和描述的,比如非博客的标题和描述等。所以到了博客的详细页中我们还需要再定义一次这些标签。如Blog/Detail.vue中的。
使用 this.$set给 定义的WebTitle等赋值。
<template>
<div class="blog-detail">
<div v-web-title :data-title="WebTitle" />
<div v-web-description :data-description="WebDescription" />
<div v-web-keywords :data-keywords="WebKeywords" />
<div v-web-author :data-author="WebAuthor" />
<article>
<header>
<h2 v-html="itemInfo.PostTitle"></h2>
</header>
<section
class="blog-content-info"
v-html="itemInfo.PostContent"
></section>
</article>
</div>
</template>
<script lang="ts">
import axios from "axios";
import GlobalFunctions from "@/api/functions";
export default {
itemInfo: Object,
WebTitle: String,
WebDescription: String,
WebKeywords: String,
WebAuthor: String,
data() {
return {
itemInfo: {},
WebTitle: "",
WebDescription: "",
WebKeywords: "",
WebAuthor: ""
};
},
mounted() {
//获取详细博客
this.handleBlogDetail();
},
watch: {
$route(to, from) {
this.handleBlogDetail();
}
},
methods: {
handleBlogDetail() {
axios
.get("/api/windigniter/blog/detail/" + this.$route.params.slug, {
params: {}
})
.then(response => {
if (response.data.Status) {
this.itemInfo = response.data.Message;
//设置标题、描述、关键字等
this.$set(
this,
"WebTitle",
response.data.Message.PostTitle + "-风火家人"
);
this.$set(this, "WebDescription", response.data.Message.PostTitle);
this.$set(this, "WebKeywords", response.data.Message.PostTitle);
this.$set(this, "WebAuthor", response.data.Message.UserEmail);
return;
}
return;
});
}
}
};
</script>
5.在 main.ts 文件中添加自定义标签,和路由处理。这里有需要注意的地方。
1.修改标题:我看有人直接使用 document.title = to.meta.title。但是我配置的上面路由方式这种并不起作用,需要使用 document.title = to.matched[0].meta.title
2.修改描述、关键字等信息。开始我使用的是 document.getElementsByTagName(“meta”)[“description”] 这种貌似在命令行里看到生效了,js出来的也对,但是看 html代码中并没有被修改,后面通过不断尝试,终于测出了正确的使用方式: document.getElementsByName(“description”)[0].content = to.matched[0].meta.description
//根据路由信息更新网页标题
router.beforeEach((to, from, next) => {
//路由发生变化修改页面title
if (to.matched[0].meta.title) {
document.title = to.matched[0].meta.title;
}
if (to.matched[0].meta.description) {
document.getElementsByName("description")[0].content =
to.matched[0].meta.description;
}
if (to.matched[0].meta.keywords) {
document.getElementsByName("keywords")[0].content =
to.matched[0].meta.keywords;
}
if (to.matched[0].meta.author) {
document.getElementsByName("author")[0].content = to.matched[0].meta.author;
}
next();
});
//自定义修改网页标题,简介,关键字
Vue.directive("web-title", {
update: function(el, binding, vnode, oldVnode) {
const { value } = binding;
if (el.dataset.title) {
document.title = el.dataset.title;
} else if (value && value.title) {
document.title = value.title;
}
}
});
Vue.directive("web-description", {
update: function(el, binding, vnode, oldVnode) {
const { value } = binding;
if (el.dataset.description) {
document.getElementsByName("description")[0].content =
el.dataset.description;
} else if (value && value.description) {
document.getElementsByName("description")[0].content = value.description;
}
}
});
Vue.directive("web-keywords", {
update: function(el, binding, vnode, oldVnode) {
const { value } = binding;
if (el.dataset.keywords) {
document.getElementsByName("keywords")[0].content = el.dataset.keywords;
} else if (value && value.keywords) {
document.getElementsByName("keywords")[0].content = el.dataset.keywords;
}
}
});
Vue.directive("web-author", {
update: function(el, binding, vnode, oldVnode) {
const { value } = binding;
if (el.dataset.author) {
document.getElementsByName("author")[0].content = el.dataset.author;
} else if (value && value.author) {
document.getElementsByName("author")[0].content = value.author;
}
}
});
现在终于可以正常显示博客详情的标题和描述等信息了。具体效果见 本站主站博客模块。
(2059)