preface
The previous chapter showed how the Vuepress theme implements inheritance, so you can modify any component and style of the default theme. We know that vuepress is not automatically available according to our Markdown file
---
tags:
- js
- vue
---
Copy the code
Generate tag cloud page, and a blog, tags in which the knowledge classification and navigation function, is an essential link, the following lead you to transform the default theme to enable it to support automatic generation of tag cloud page
Step 1 Configuration modification
Since it’s a theme, you need to provide customizability, and if someone doesn’t need the tag functionality, they need to meet that requirement by opening the config.js file and modifying the configuration in it
themeConfig: { ... tags:"/tags", ... Nav: [{... the text: "tag clouds", link: '/ tags/' tags: true},... . }Copy the code
The reason I’m doing this is because NAV is adding a menu to the header, tags:”/tags” is defining the tag routing path, so that no matter what name my tag is defined by, I can navigate to the right location.
The second step is folder creation
Since vuepress generates routes based on the Markdown file, a page that wants to generate a tag must also create a Markdown file. Create a tags folder under the.vuepress folder with a new readme.md file. Restart the project to see
Step 3 create a Tags component
In docs /. / vuepress/theme components under the new Tags. The vue file. In order for pages to automatically integrate with tag components, you need to modify the Layout.vue component. Now copy the default theme Layout components to the docs /. / layouts vuepress/theme directory (if you don’t know how to copy the Layout of the default theme please see previous section), modify one
. </Sidebar> <! - the sidebar - > < Home v - if = "$page. The frontmatter. Home" / > <! <Tags v-else-if=" Tags "/> <Page v-else :sidebar-items="sidebarItems" > <slot name="page-top" slot="top" /> <slot name="page-bottom" slot="bottom" /> </Page> ...Copy the code
The determination of tags variables in script
export default {
...
data() {
return{... tags:false}},...created(){
this.checkTags()
}
...
checkTags() {
path=this.$route.path
let tags = this.$site.themeConfig.nav.filter(v => v.tags); / / determine tagsif (tags[0].link === path) {
this.tags = true;
this.$page.frontmatter.sidebar = false; // Tags do not need a sidebar}else {
this.tags = false; } // Check whether it is a category pagelet type = this.$page.frontmatter.type;
if (type= = ="classify") {
this.type = "classify";
this.$page.frontmatter.sidebar = false; // Tags do not need a sidebar}else {
this.type = "";
}
if (this.$page.frontmatter.defaultHome) {
this.$page.frontmatter.sidebar = false; // The home page does not need a sidebar}}}Copy the code
Import the Tags component, where Tags determine whether the current page routing Tags are true, an option configured in config.js. Add the following content to the newly created Tags. Vue file. This is the tag component defined by me, and you can modify it according to my component
<template> <div> <div class="content default"></div> <div class="tag"> <div class="items"> <span v-for="taginfo in tags" :style="{backgroundColor:color()}" @click="change(taginfo.tag)" :class="taginfo.tag===tg? 'active':''" >{{taginfo.tag}}({{taginfo.number}})</span> </div> <div class="article-list"> <Article v-for="tag in info" :tag="tag" :tg="tg" @turnTo="change"/> </div> </div> </div> </template> <script> import Article from "@theme/components/Article.vue"; export default { components: { Article }, data() { return { info: [], tg: "" }; }, computed: {tags() {// core code, integrate the number of tags in markDown let allTags = []; this.$site.pages.forEach(v => { if (v.frontmatter.tags) { allTags.push(v.frontmatter.tags); } else if (v.frontmatter.tag) { allTags.push(v.frontmatter.tag); }}); allTags = allTags.join(",").split(","); let flatTags = Array.from(new Set(allTags)); return flatTags.reduce((res, v) => { let o = {}; o.tag = v; o.number = allTags.filter(value => value === v).length; res.push(o); return res; } []); }}, methods: {change(tag) {this.tg = tag;}}, methods: {change(tag) { this.info = this.$site.pages.filter(v => { let tags = v.frontmatter.tags; if (tags) { return tags.some(v => v === tag); }}); }, color () {/ / tag button color let colors = [" # 3498 db ", "# 3 eaf7c", "# 5 cbbf6", "# f5A28E", "# f2AC3B", "# FA6551", "#C68CE0" ]; return colors[parseInt(Math.random() * colors.length)]; }}, mounted() {// When routing? Let tag= this.$route.query. Tag; if (tag) { this.change(tag); }}}; Word-wrap: break-word! Important; "> < span style ='stylus' scoped>.tag {max-width: 46.rem; margin: 0 auto; 2.5 rem padding: 0; .items { margin-bottom: 2rem; span { vertical-align: middle; cursor: pointer; Margin: 0.5 rem 0.5 rem 0.2 rem. Padding: 0.4 rem 0.7 rem; display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; Border - the radius: 0.2 rem; background: #fff; color: #fff; font-size: 1rem; Box-shadow: 0 1px 0.25rem 0 hSLA (0, 0%, 57%, 0.21); box-shadow: 0 1px 0.25rem 0 hSLA (0, 0%, 57%, 0.21); The transition: all 0.3 s; background-color: red; &. Active {transform: scale (1.2); } &:hover {transform: scale(1.2); } } } } </style>Copy the code
The Article component is the part of the tag that displays the content of the Article. You can define your own component and style. I attach my own Article component
<template> <div class="abstract"> <div class="abstract-item"> <div class="text-hover"> <router-link :to="tag.path">{{tag.title}}</router-link> </div> <! ----> <div class="abstract"> <div class="tip custom-block" v-if="tag.excerpt"> <! -- <p class="custom block-title">{{tag.title}}</p> <p> </ul>--> <div v-html="tag.excerpt"></div> </div> </div> <div class="details-btn"> <router-link :to="tag.path"> <div ">< div style =" box-sizing: border-box; color: RGB (74, 74, 74); line-height: 22px; font-size: 13px! Important; white-space: normal; class="v-divider"></div> <div class="article-info article-info-item"> <i class="what"> <em v-if="tag.lastUpdated">{{tag.lastUpdated}}</em> </i> <i class="what" v-for="t in tag.frontmatter.tags"> <em class="text-item active" v-if="t==tg">{{t}}</em> <em class="text-item" v-else @click="$emit('turnTo',t)">{{t}}</em> </i> <! -- <i class="iconfont h-classify article-info-item" class="what" > <em class="text-item">IDE</em> </i>--> </div> </div> < div> </template> <script> export default {props: {tag: {}, // indexing data tg: ""}}; </script> <style lang="stylus" scoped> $color = #3eaf7c; .abstract { margin-top: 1rem; width: 100%; . Abstract -item {margin: 0 auto 1.2rem; Padding: 1 rem 1.2 rem; width: 100%; overflow: hidden; Border - the radius: 0.3 rem; -webkit-box-sizing: border-box; box-sizing: border-box; - its - the transition: all 0.3 s; The transition: all 0.3 s; -webkit-box-shadow: 0 0.25rem 1.2rem 0 hSLA (0, 0%, 57%, 0.21); Box-shadow: 0 0.25rem 1.2rem 0 hSLA (0, 0%, 57%, 0.21); background-color: #fff; position: relative; .abstract { } .text-hover { position: relative; The font - size: 1.2 rem; line-height: 2rem; display: inline-block; a { &:after { content: ''; position: absolute; width: 101%; height: 2px; bottom: 0; left: 0; background-color: $color; visibility: hidden; -webkit-transform: scaleX(0); transform: scaleX(0); - its - the transition: 0.3 s ease - in-out; The transition: 0.3 s ease - in-out; } &:hover:after { visibility: visible; -webkit-transform: scaleX(1); transform: scaleX(1); } } } .details-btn { text-align: right; Margin: 0.6 rem 0; .v-btn { display: inline-block; The font - size: 0.8 rem; Padding: 0.4 rem 0.7 rem; cursor: pointer; Letter - spacing: 0.1 em. - its - the transition: all 0.3 s; The transition: all 0.3 s; background-color: #efefef; color: #2c3e50; Border - the radius: 0.1 rem; The line - height: 1.2; &:hover { background-color: $color; color: #fff; } } } .article-info { margin-right: 1rem; The line - height: 1.6 rem; margin-right: 1rem; The line - height: 1.6 rem; font-style: normal; .text-item { font-weight: 700; border: 1px $color; font-style: normal; Margin - left: 0.4 rem; cursor: pointer; background-color: #f6f6f6; Padding: 0.2 rem 0.4 rem; &.active { color: $color; } &:hover { color: $color; } } } .v-divider { display: block; -webkit-box-flex: 1; -ms-flex: 1 1 0px; flex: 1 1 0px; max-width: 100%; height: 0; max-height: 0; border: solid; border-width: thin 0 0 0; -webkit-transition: inherit; transition: inherit; border-color: rgb(234, 236, 239); Margin - top: 0.7 rem; Margin - bottom: 0.7 rem; Mso-font-weight: 0pt; mso-font-weight: 0pt; mso-font-weight: 0pt; color: rgb(153, 153, 153); } </style>Copy the code
At this point, the tag cloud page is complete and looks like this
Step 4 Display the TAB page and jump to the TAB page
The Page component is the content component for the article to display. If you want to display the tag at the head of the article when the article is displayed, you need to modify the Page component.
In the components of the default theme Page. Vue file is copied to the docs /. / components vuepress/theme, modify the content
<slot name="top"/> <! <section class="tags" v-if="this.$site.themeconfig. Tags &&tags&&tags.length>0"> <! $page. Frontmatter. Tags. This is an array of tags generated by compiling tags in the Markdown file by Vuepress. --> <span class="tagPopup" v-for="tag in tags"> <! -- $site.themeconfig. Tags is the tags directory specified in config.js --> <router-link :to="'/'+$site.themeconfig. Tags +'/? tag='+tag" class="tag">{{tag}}</router-link> </span> </section> <! --> <Content/>Copy the code
The modified effect is as follows
At this point, the transformation of the tag cloud is almost complete. Here is the source address I modified: vuepress-theme-reform
Check out the results on my blog