feat: 添加一些小功能&使config支持ts(未完成)

This commit is contained in:
xugaoyi 2022-01-01 23:49:51 +08:00
parent 41e7fac18b
commit fc34b35537
16 changed files with 430 additions and 322 deletions

View File

@ -1,9 +1,17 @@
const baiduCode = require('./config/baiduCode.js'); // 百度统计hm码
const htmlModules = require('./config/htmlModules.js');
import { resolve } from 'path'
import { defineConfig4CustomTheme } from 'vuepress/config'
import { VdoingThemeConfig } from '../../theme-vdoing/types'
// import { VdoingThemeConfig } from 'vuepress-theme-vdoing/types'
import dayjs from 'dayjs'
import baiduCode from './config/baiduCode' // 百度统计hm码
import htmlModules from './config/htmlModules' // 自定义插入的html块
module.exports = {
theme: 'vdoing', // 使用npm包主题
// theme: require.resolve('../../theme-vdoing'), // 使用本地主题
export default defineConfig4CustomTheme<VdoingThemeConfig>({
// theme: 'vdoing', // 使用npm包主题
theme: resolve(__dirname, '../../theme-vdoing'), // 使用本地主题
title: "Evan's blog",
description: 'web前端技术博客,专注web前端学习与总结。JavaScript,js,ES6,TypeScript,vue,React,python,css3,html5,Node,git,github等技术文章。',
@ -123,8 +131,7 @@ module.exports = {
// 'https://cdn.jsdelivr.net/gh/xugaoyi/image_store/blog/20200507175845.jpeg',
// 'https://cdn.jsdelivr.net/gh/xugaoyi/image_store/blog/20200507175846.jpeg'
// ], // body背景大图默认无。 单张图片 String | 多张图片 Array, 多张图片时每隔15秒换一张。
// bodyBgImgOpacity: 0.5, // body背景图透明度选值 0 ~ 1.0, 默认0.5
// bodyBgImgOpacity: 0.5, // body背景图透明度选值 0.1~ 1.0, 默认0.5
// titleBadge: false, // 文章标题前的图标是否显示默认true
// titleBadgeIcons: [ // 文章标题前图标的地址,默认主题内置图标
// '图标地址1',
@ -141,6 +148,7 @@ module.exports = {
// pageButton: false, // 是否显示快捷翻页按钮默认true
// 侧边栏 'structuring' | { mode: 'structuring', collapsable: Boolean} | 'auto' | <自定义> 温馨提示:目录页数据依赖于结构化的侧边栏数据,如果你不设置为'structuring',将无法使用目录页
// @ts-ignore
sidebar: 'structuring',
// 文章默认的作者信息可在md文件中单独配置此信息 String | {name: String, link: String}
@ -201,123 +209,111 @@ module.exports = {
],
['meta', { name: 'baidu-site-verification', content: '7F55weZDDc' }], // 百度统计的站长验证(你可以去掉)
['meta', { name: 'theme-color', content: '#11a8cd' }], // 移动浏览器主题颜色
[
'script',
{
'data-ad-client': 'ca-pub-7828333725993554',
async: 'async',
src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
},
], // 网站关联Google AdSense 与 html格式广告支持你可以去掉
// [
// 'script',
// {
// 'data-ad-client': 'ca-pub-7828333725993554',
// async: 'async',
// src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
// },
// ], // 网站关联Google AdSense 与 html格式广告支持你可以去掉
],
// 插件配置
plugins: [
// 本地插件(供学习)
// [require('./plugins/love-me'), { // 鼠标点击爱心特效
plugins: {
// 导入本地插件(供学习参考
// [resolve(__dirname, './plugins/love-me')]: { // 鼠标点击爱心特效
// color: '#11a8cd', // 爱心颜色,默认随机色
// excludeClassName: 'theme-vdoing-content' // 要排除元素的class, 默认空''
// }],
// },
'vuepress-plugin-baidu-autopush', // 百度自动推送
// 百度自动推送
'vuepress-plugin-baidu-autopush': {},
// 可以添加第三方搜索链接的搜索框(原官方搜索框的参数仍可用)
[
'thirdparty-search',
{
thirdparty: [
// 可选,默认 []
{
title: '在MDN中搜索',
frontUrl: 'https://developer.mozilla.org/zh-CN/search?q=', // 搜索链接的前面部分
behindUrl: '', // 搜索链接的后面部分,可选,默认 ''
},
{
title: '在Runoob中搜索',
frontUrl: 'https://www.runoob.com/?s=',
},
{
title: '在Vue API中搜索',
frontUrl: 'https://cn.vuejs.org/v2/api/#',
},
{
title: '在Bing中搜索',
frontUrl: 'https://cn.bing.com/search?q=',
},
{
title: '通过百度搜索本站的',
frontUrl: 'https://www.baidu.com/s?wd=site%3Axugaoyi.com%20',
},
],
},
],
// 百度统计
'vuepress-plugin-baidu-tongji': {
hm: baiduCode,
},
[
'one-click-copy', // 代码块复制按钮
{
copySelector: ['div[class*="language-"] pre', 'div[class*="aside-code"] aside'], // String or Array
copyMessage: '复制成功', // default is 'Copy successfully and then paste it for use.'
duration: 1000, // prompt message display time.
showInMobile: false, // whether to display on the mobile side, default: false.
},
],
// 可以添加第三方搜索链接的搜索框(继承原官方搜索框的配置参数)
'thirdparty-search': {
thirdparty: [
{
title: '在MDN中搜索',
frontUrl: 'https://developer.mozilla.org/zh-CN/search?q=', // 搜索链接的前面部分
behindUrl: '', // 搜索链接的后面部分,可选,默认 ''
},
{
title: '在Runoob中搜索',
frontUrl: 'https://www.runoob.com/?s=',
},
{
title: '在Vue API中搜索',
frontUrl: 'https://cn.vuejs.org/v2/api/#',
},
{
title: '在Bing中搜索',
frontUrl: 'https://cn.bing.com/search?q=',
},
{
title: '通过百度搜索本站的',
frontUrl: 'https://www.baidu.com/s?wd=site%3Axugaoyi.com%20',
},
],
},
[
'demo-block', // demo演示模块 https://github.com/xiguaxigua/vuepress-plugin-demo-block
{
settings: {
// jsLib: ['http://xxx'], // 在线示例(jsfiddle, codepen)中的js依赖
// cssLib: ['http://xxx'], // 在线示例中的css依赖
// vue: 'https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js', // 在线示例中的vue依赖
jsfiddle: false, // 是否显示 jsfiddle 链接
codepen: true, // 是否显示 codepen 链接
horizontal: false, // 是否展示为横向样式
},
// 代码块复制按钮
'one-click-copy': {
copySelector: ['div[class*="language-"] pre', 'div[class*="aside-code"] aside'], // String or Array
copyMessage: '复制成功', // default is 'Copy successfully and then paste it for use.'
duration: 1000, // prompt message display time.
showInMobile: false, // whether to display on the mobile side, default: false.
},
// DEMO演示模块, API: https://github.com/xiguaxigua/vuepress-plugin-demo-block
'demo-block': {
settings: {
// jsLib: ['http://xxx'], // 在线示例(jsfiddle, codepen)中的js依赖
// cssLib: ['http://xxx'], // 在线示例中的css依赖
// vue: 'https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js', // 在线示例中的vue依赖
jsfiddle: false, // 是否显示 jsfiddle 链接
codepen: true, // 是否显示 codepen 链接
horizontal: false, // 是否展示为横向样式
},
],
[
'vuepress-plugin-zooming', // 放大图片
{
selector: '.theme-vdoing-content img:not(.no-zoom)', // 排除class是no-zoom的图片
options: {
bgColor: 'rgba(0,0,0,0.6)',
},
},
// 放大图片
'vuepress-plugin-zooming': {
selector: '.theme-vdoing-content img:not(.no-zoom)', // not排除class是no-zoom的图片
options: {
bgColor: 'rgba(0,0,0,0.6)',
},
],
[
'vuepress-plugin-baidu-tongji', // 百度统计 (你可以去掉)
{
hm: baiduCode || '503f098e7e5b3a5b5d8c5fc2938af002',
},
// 评论区
'vuepress-plugin-comment': {
choosen: 'gitalk',
options: {
clientID: 'a6e1355287947096b88b',
clientSecret: 'f0e77d070fabfcd5af95bebb82b2d574d7248d71',
repo: 'blog-gitalk-comment', // GitHub 仓库
owner: 'xugaoyi', // GitHub仓库所有者
admin: ['xugaoyi'], // 对仓库有写权限的人
// distractionFreeMode: true,
pagerDirection: 'last', // 'first'正序 | 'last'倒序
id: '<%- (frontmatter.permalink || frontmatter.to.path).slice(-16) %>', // 页面的唯一标识,长度不能超过50
title: '「评论」<%- frontmatter.title %>', // GitHub issue 的标题
labels: ['Gitalk', 'Comment'], // GitHub issue 的标签
body:
'页面:<%- window.location.origin + (frontmatter.to.path || window.location.pathname) %>', // GitHub issue 的内容
},
],
[
'vuepress-plugin-comment', // 评论
{
choosen: 'gitalk',
options: {
clientID: 'a6e1355287947096b88b',
clientSecret: 'f0e77d070fabfcd5af95bebb82b2d574d7248d71',
repo: 'blog-gitalk-comment', // GitHub 仓库
owner: 'xugaoyi', // GitHub仓库所有者
admin: ['xugaoyi'], // 对仓库有写权限的人
// distractionFreeMode: true,
pagerDirection: 'last', // 'first'正序 | 'last'倒序
id: '<%- (frontmatter.permalink || frontmatter.to.path).slice(-16) %>', // 页面的唯一标识,长度不能超过50
title: '「评论」<%- frontmatter.title %>', // GitHub issue 的标题
labels: ['Gitalk', 'Comment'], // GitHub issue 的标签
body:
'页面:<%- window.location.origin + (frontmatter.to.path || window.location.pathname) %>', // GitHub issue 的内容
},
},
// "上次更新"的时间格式
'@vuepress/last-updated': {
transformer: (timestamp, lang) => {
return dayjs(timestamp).format('YYYY/MM/DD, HH:mm:ss')
},
],
[
'@vuepress/last-updated', // "上次更新"时间格式
{
transformer: (timestamp, lang) => {
const dayjs = require('dayjs') // https://day.js.org/
return dayjs(timestamp).format('YYYY/MM/DD, HH:mm:ss')
},
},
],
],
}
},
},
})

View File

@ -1 +1 @@
module.exports = '';
export default '503f098e7e5b3a5b5d8c5fc2938af002'

View File

@ -18,7 +18,7 @@
* ②注windowLB windowRB1.展示区块最大宽高200px*400px2.请给自定义元素定一个不超过200px*400px的宽高3.在屏幕宽度小于960px时无论如何都不会显示
*/
module.exports = {
const htmlModule = {
homeSidebarB:
`<div style="padding: 0.95rem">
<p style="
@ -110,7 +110,7 @@ module.exports = {
}
// module.exports = {
// const htmlModule = {
// homeSidebarB: `<div style="width:100%;height:100px;color:#fff;background: #eee;">自定义模块测试</div>`,
// sidebarT: `<div style="width:100%;height:100px;color:#fff;background: #eee;">自定义模块测试</div>`,
// sidebarB: `<div style="width:100%;height:100px;color:#fff;background: #eee;">自定义模块测试</div>`,
@ -119,3 +119,6 @@ module.exports = {
// windowLB: `<div style="width:100%;height:100px;color:#fff;background: #eee;">自定义模块测试</div>`,
// windowRB: `<div style="width:100%;height:100px;color:#fff;background: #eee;">自定义模块测试</div>`,
// }
export default htmlModule

View File

@ -2,12 +2,12 @@
title: Markdown使用教程
date: 2019-12-25 14:27:01
permalink: /pages/ad247c4332211551
categories:
categories:
- 技术
- 技术文档
tags:
tags:
- null
author:
author:
name: xugaoyi
link: https://github.com/xugaoyi
---
@ -192,7 +192,7 @@ Markdown 段落没有特殊的格式,直接编写文字,**需要段落缩进
### 字体
```markdown
*斜体文本*
*斜体文本*
或 _斜体文本_
**粗体文本**
或 __粗体文本__
@ -245,10 +245,10 @@ ___粗斜体文本___
文字高亮能使行内部分文字高亮,使用一对反引号。
```markdown
`html` `css` `javascript`
`html` `css` `javascript`
```
`html` `css` `javascript`
`html` `css` `javascript`
@ -435,7 +435,7 @@ ___粗斜体文本___
- [ ] 第三项
### 列表嵌套
@ -537,7 +537,7 @@ ___粗斜体文本___
如果是段落上的一个代码片段可以用反引号把它包起来(**`**),示例:
```markdown
`alert()`
`alert()`
```
`alert()`
@ -648,7 +648,7 @@ function test() {
[Markdown](#一Markdown)
[链接](#九链接)
[链接](#九链接)
[流程图](#流程图)
@ -665,7 +665,7 @@ function test() {
当然,你也可以像链接那样对图片地址使用变量:
```markdown
这里链接用 img 作为图片地址变量
这里链接用 img 作为图片地址变量
然后在文档的结尾或其他位置给变量赋值(图片地址)
![RUNOOB][img]
[img]: https://raw.githubusercontent.com/xugaoyi/image_store/master/blog/md_logo.png
@ -740,7 +740,7 @@ github上如果引用其他github仓库中的图片则要注意地址格式`
**对齐方式**
- **-:** 设置内容和标题栏居右对齐
- **-:** 设置内容和标题栏居右对齐
- **:-** 设置内容和标题栏居左对齐
- **:-:** 设置内容和标题栏居中对齐
@ -798,11 +798,11 @@ Emoji表情英文名的前后加冒号Typore上先输入冒号再输入首字
Markdown 使用了很多特殊符号来表示特定的意义,如果需要显示特定的符号则需要使用反斜杠转义字符:
```markdown
**未转义星号显示加粗**
**未转义星号显示加粗**
\*\* 转义显示星号 \*\*
```
**未转义星号显示加粗**
**未转义星号显示加粗**
\*\* 转义显示星号 \*\*
@ -840,7 +840,7 @@ _ 下划线
```markdown
$$
\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix}
\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix}
\mathbf{i} & \mathbf{j} & \mathbf{k} \\
\frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\
\frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 \\
@ -851,7 +851,7 @@ $$
$$
\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix}
\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix}
\mathbf{i} & \mathbf{j} & \mathbf{k} \\
\frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\
\frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 \\
@ -860,7 +860,7 @@ $$
### 图表
```markdown
````markdown
```chart
,Budget,Income,Expenses,Debt
June,5000,8000,4000,6000
@ -881,31 +881,14 @@ sequenceDiagram
A->>B: 是否已收到消息?
B-->>A: 已收到消息
```
```
````
> 注在Typora中未支持
```chart
,Budget,Income,Expenses,Debt
June,5000,8000,4000,6000
July,3000,1000,4000,3000
Aug,5000,7000,6000,3000
Sep,7000,2000,3000,1000
Oct,6000,5000,4000,2000
Nov,4000,3000,5000,
type: pie
title: Monthly Revenue
x.title: Amount
y.title: Month
y.suffix: $
```
### 流程图
```markdown
````markdown
语法:
```mermaid
graph TD
@ -915,7 +898,7 @@ C -->|条件C1| D[模块D]
C -->|条件C2| E[模块E]
C -->|条件C3| F[模块F]
```
```
````
流程图相关文章:
@ -923,40 +906,26 @@ C -->|条件C3| F[模块F]
<http://www.imooc.com/article/292708>
```mermaid
graph TD
A[模块A] -->|A1| B(模块B)
B --> C{判断条件C}
C -->|条件C1| D[模块D]
C -->|条件C2| E[模块E]
C -->|条件C3| F[模块F]
```
### 时序图
```markdown
````markdown
```mermaid
sequenceDiagram
A->>B: 是否已收到消息?
B-->>A: 已收到消息
```
```
````
```mermaid
sequenceDiagram
A->>B: 是否已收到消息?
B-->>A: 已收到消息
```
### 甘特图
### 甘特图
``` markdown
```` markdown
```mermaid
gantt
title 甘特图
@ -968,18 +937,6 @@ section 项目B
任务3 :2018-06-12 , 12d
任务4 : 24d
```
```
````
```mermaid
gantt
title 甘特图
dateFormat YYYY-MM-DD
section 项目A
任务1 :a1, 2018-06-06, 30d
任务2 :after a1 , 20d
section 项目B
任务3 :2018-06-12 , 12d
任务4 : 24d
```
[回到顶部](#markdown使用教程)
[回到顶部](#markdown使用教程)

View File

@ -2,6 +2,7 @@
title: 一行代码“黑”掉任意网站
date: 2021-11-25 14:33:51
permalink: /pages/dcebaf/
titleTag: 原创
sticky: 1
categories:
- 更多

View File

@ -15,7 +15,7 @@ author:
### 加载渲染过程
```repl
```text
父beforeCreate -> 父created-> 父beforeMount-> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
```
@ -23,18 +23,18 @@ author:
### 子组件更新过程
```repl
```text
父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated
```
### 父组件更新过程
```repl
```text
父beforeUpdate -> 父updated
```
### 销毁过程
```repl
```text
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
```

View File

@ -15,7 +15,7 @@
"dayjs": "^1.9.7",
"inquirer": "^7.1.0",
"json2yaml": "^1.1.0",
"vuepress": "1.8.0",
"vuepress": "1.9.2",
"vuepress-plugin-baidu-autopush": "^1.0.1",
"vuepress-plugin-baidu-tongji": "^1.0.1",
"vuepress-plugin-demo-block": "^0.7.2",

View File

@ -6,8 +6,11 @@
:src="currentBadge"
v-if="$themeConfig.titleBadge === false ? false : true"
/>
{{ this.$page.title }}
{{ $page.title }}
</h1>
<div class="count">
总共 <i>{{ $sortPostsByDate.length }}</i> 篇文章
</div>
<ul>
<template v-for="(item, index) in postsList">
<li
@ -15,12 +18,20 @@
v-if="(year = getYear(index)) !== getYear(index - 1)"
:key="index + $sortPostsByDate.length"
>
<h2>{{ year }}</h2>
<h2>
{{ year }}
<span>
<i>{{ countByYear[year] }}</i>
</span>
</h2>
</li>
<li :key="index">
<router-link :to="item.path">
<span>{{ getDate(item) }}</span>
<span class="date">{{ getDate(item) }}</span>
{{ item.title }}
<span class="title-tag" v-if="item.frontmatter.titleTag">
{{ item.frontmatter.titleTag }}
</span>
</router-link>
</li>
</template>
@ -36,19 +47,34 @@ import TitleBadgeMixin from '../mixins/titleBadge'
export default {
mixins: [TitleBadgeMixin],
data () {
data() {
return {
postsList: [],
countByYear: {}, //
perPage: 80, //
currentPage: 1//
}
},
created () {
created() {
this.getPageData()
},
mounted () {
//
const { $sortPostsByDate, countByYear } = this
for (let i = 0; i < $sortPostsByDate.length; i++) {
const { frontmatter: { date } } = $sortPostsByDate[i];
if (date && type(date) === 'string') {
const year = date.slice(0, 4)
if (!countByYear[year]) {
countByYear[year] = 0
}
countByYear[year] = countByYear[year] + 1
}
}
this.countByYear = countByYear
},
mounted() {
window.addEventListener('scroll', debounce(() => {
if (this.postsList.length < this.$sortPostsByDate.length) {
const docEl = document.documentElement
@ -65,29 +91,29 @@ export default {
}, 200))
},
methods: {
getPageData () {
getPageData() {
const currentPage = this.currentPage
const perPage = this.perPage
this.postsList = this.postsList.concat(this.$sortPostsByDate.slice((currentPage - 1) * perPage, currentPage * perPage))
},
loadmore () {
loadmore() {
this.currentPage = this.currentPage + 1
this.getPageData()
},
getYear (index) {
getYear(index) {
const item = this.postsList[index]
if (!item) {
return
}
const { frontmatter: { date } } = item
if (date && type(date) === 'string') {
return date.split(" ")[0].slice(0, 4)
return date.slice(0, 4)
}
},
getDate (item) {
getDate(item) {
const { frontmatter: { date } } = item
if (date && type(date) === 'string') {
return date.split(" ")[0].slice(5, 10)
return date.slice(5, 10)
}
}
}
@ -103,9 +129,16 @@ export default {
position relative
@media (min-width $contentWidth + 80)
margin-top 1.5rem !important
.count
text-align right
margin-top -2.5rem
font-size 0.85rem
opacity 0.8
ul, li
margin 0
padding 0
ul
margin-top 2rem
li
list-style none
&.year
@ -119,6 +152,11 @@ export default {
margin-bottom 0.8rem
font-weight 400
padding 0.5rem 0
span
font-size 0.85rem
font-weight 300
float right
margin-top 1rem
a
display block
color var(--textColor)
@ -134,11 +172,22 @@ export default {
font-weight normal
&:hover
padding-left 1.5rem
span
span.date
opacity 0.6
font-size 0.85rem
font-weight 400
margin-right 0.3rem
.title-tag
// height 1.1rem
// line-height 1.1rem
border 1px solid $activeColor
color $activeColor
font-size 0.8rem
padding 0 0.35rem
border-radius 0.2rem
margin-left 0rem
transform translate(0, -0.05rem)
display inline-block
.loadmore
text-align center
margin-top 1rem

View File

@ -1,7 +1,6 @@
<template>
<div>
<main class="page">
<div :class="`theme-vdoing-wrapper ${bgStyle}`">
<ArticleInfo v-if="isArticle()" />
<component
@ -12,26 +11,27 @@
<div class="content-wrapper">
<RightMenu v-if="showRightMenu" />
<h1 v-if="showTitle">
<img
:src="currentBadge"
v-if="$themeConfig.titleBadge === false ? false : true"
/>
{{this.$page.title}}
/>{{ this.$page.title
}}<span class="title-tag" v-if="$frontmatter.titleTag">{{
$frontmatter.titleTag
}}</span>
</h1>
<slot name="top" v-if="isShowSlotT" />
<Content class="theme-vdoing-content" />
</div>
<slot name="bottom" v-if="isShowSlotB" />
<slot name="bottom" v-if="isShowSlotB" />
<PageEdit />
<PageNav v-bind="{ sidebarItems }" />
</div>
<UpdateArticle
:length="3"
:moreArticle="updateBarConfig && updateBarConfig.moreArticle"
@ -53,28 +53,28 @@ import TitleBadgeMixin from '../mixins/titleBadge'
export default {
mixins: [TitleBadgeMixin],
data () {
data() {
return {
updateBarConfig: null
}
},
props: ['sidebarItems'],
components: { PageEdit, PageNav, ArticleInfo, Catalogue, UpdateArticle, RightMenu },
created () {
created() {
this.updateBarConfig = this.$themeConfig.updateBar
},
computed: {
bgStyle () {
bgStyle() {
const { contentBgStyle } = this.$themeConfig
return contentBgStyle ? 'bg-style-' + contentBgStyle : ''
},
isShowUpdateBar () {
isShowUpdateBar() {
return this.updateBarConfig && this.updateBarConfig.showToArticle === false ? false : true
},
showTitle () {
showTitle() {
return !this.$frontmatter.pageComponent
},
showRightMenu () {
showRightMenu() {
const { $frontmatter, $themeConfig, $page } = this
const { sidebar } = $frontmatter
return (
@ -83,7 +83,7 @@ export default {
($frontmatter && sidebar && sidebar !== false) !== false
)
},
pageComponent () {
pageComponent() {
return this.$frontmatter.pageComponent ? this.$frontmatter.pageComponent.name : false
},
isShowSlotT() {
@ -96,16 +96,16 @@ export default {
methods: {
getShowStatus(prop) {
const { htmlModules } = this.$themeConfig
if(!htmlModules) return false
if (!htmlModules) return false
if (htmlModules[prop] === 'article') { //
return this.isArticle()
} else if (htmlModules[prop] === 'custom'){ //
} else if (htmlModules[prop] === 'custom') { //
return !(this.isArticle())
} else { //
return true
}
},
isArticle () {
isArticle() {
return this.$frontmatter.article !== false
}
}
@ -121,16 +121,29 @@ export default {
@media (max-width $MQMobile)
padding-top $navbarHeight
@media (min-width $MQMobile)
padding-top ($navbarHeight + 1.5rem)
padding-top: ($navbarHeight + 1.5rem)
>*
@extend $vdoing-wrapper
.theme-vdoing-wrapper
.content-wrapper
position relative
h1 img
margin-bottom -0.2rem
max-width 2.2rem
max-height 2.2rem
h1
.title-tag
height 1.5rem
line-height 1.5rem
border 1px solid $activeColor
color $activeColor
font-size 1rem
padding 0 0.4rem
border-radius 0.2rem
margin-left 0.5rem
transform translate(0, -0.25rem)
display inline-block
img
margin-bottom -0.2rem
margin-right 0.2rem
max-width 2.2rem
max-height 2.2rem
.theme-vdoing-wrapper
--linesColor rgba(50, 0, 0, 0.05)
&.bg-style-1 //

View File

@ -1,12 +1,6 @@
<template>
<div
class="post-list"
ref="postList"
>
<transition-group
tag="div"
name="post"
>
<div class="post-list" ref="postList">
<transition-group tag="div" name="post">
<div
class="post card-box"
:class="item.frontmatter.sticky && 'iconfont icon-zhiding'"
@ -15,7 +9,12 @@
>
<div class="title-wrapper">
<h2>
<router-link :to="item.path">{{item.title}}</router-link>
<router-link :to="item.path">
{{ item.title }}
<span class="title-tag" v-if="item.frontmatter.titleTag">{{
item.frontmatter.titleTag
}}</span>
</router-link>
</h2>
<div class="article-info">
<a
@ -24,54 +23,60 @@
target="_blank"
v-if="item.author && item.author.href"
:href="item.author.href"
>{{ item.author.name ? item.author.name : item.author }}</a>
>{{ item.author.name ? item.author.name : item.author }}</a
>
<span
title="作者"
class="iconfont icon-touxiang"
v-else-if="item.author"
>{{ item.author.name ? item.author.name : item.author }}</span>
>{{ item.author.name ? item.author.name : item.author }}</span
>
<span
title="创建时间"
class="iconfont icon-riqi"
v-if="item.frontmatter.date"
>{{ item.frontmatter.date.split(' ')[0]}}</span>
>{{ item.frontmatter.date.split(' ')[0] }}</span
>
<span
title="分类"
class="iconfont icon-wenjian"
v-if="$themeConfig.category !== false && item.frontmatter.categories"
v-if="
$themeConfig.category !== false && item.frontmatter.categories
"
>
<router-link
:to="`/categories/?category=${encodeURIComponent(c)}`"
v-for="(c, index) in item.frontmatter.categories"
:key="index"
>{{c}}</router-link>
>{{ c }}</router-link
>
</span>
<span
title="标签"
class="iconfont icon-biaoqian tags"
v-if="$themeConfig.tag !== false && item.frontmatter.tags && item.frontmatter.tags[0]"
v-if="
$themeConfig.tag !== false &&
item.frontmatter.tags &&
item.frontmatter.tags[0]
"
>
<router-link
:to="`/tags/?tag=${encodeURIComponent(t)}`"
v-for="(t, index) in item.frontmatter.tags"
:key="index"
>{{t}}</router-link>
>{{ t }}</router-link
>
</span>
</div>
</div>
<div
class="excerpt-wrapper"
v-if="item.excerpt"
>
<div
class="excerpt"
v-html="item.excerpt"
></div>
<div class="excerpt-wrapper" v-if="item.excerpt">
<div class="excerpt" v-html="item.excerpt"></div>
<router-link
:to="item.path"
class="readmore iconfont icon-jiantou-you"
>阅读全文</router-link>
>阅读全文</router-link
>
</div>
</div>
</transition-group>
@ -98,20 +103,20 @@ export default {
default: 10
}
},
data () {
data() {
return {
sortPosts: [],
postListOffsetTop: 0
}
},
created () {
created() {
this.setPosts()
},
mounted () {
mounted() {
// this.postListOffsetTop = this.getElementToPageTop(this.$refs.postList) - 240
},
watch: {
currentPage () {
currentPage() {
if (this.$route.query.p != this.currentPage) { // 退
this.$router.push({
query: {
@ -125,15 +130,15 @@ export default {
// },0)
this.setPosts()
},
category () {
category() {
this.setPosts()
},
tag () {
tag() {
this.setPosts()
}
},
methods: {
setPosts () {
setPosts() {
const currentPage = this.currentPage
const perPage = this.perPage
@ -187,7 +192,19 @@ export default {
margin 0.5rem 0
font-size 1.4rem
border none
.title-tag
height 1.2rem
line-height 1.2rem
border 1px solid $activeColor
color $activeColor
font-size 0.8rem
padding 0 0.35rem
border-radius 0.2rem
margin-left 0rem
transform translate(0, -0.15rem)
display inline-block
a
display block
@media (max-width $MQMobile)
font-weight 400
.article-info

View File

@ -1,32 +1,32 @@
<template>
<div :class="['article-list',{'no-article-list': isShowArticle}]">
<div :class="['article-list', { 'no-article-list': isShowArticle }]">
<div class="article-title">
<router-link
:to="moreArticle || '/archives/'"
class="iconfont icon-bi"
>最近更新</router-link>
<router-link :to="moreArticle || '/archives/'" class="iconfont icon-bi"
>最近更新</router-link
>
</div>
<div class="article-wrapper">
<dl
v-for="(item, index) in topPublishPosts"
:key="index"
>
<dd>{{getNum(index)}}</dd>
<dl v-for="(item, index) in topPublishPosts" :key="index">
<dd>{{ getNum(index) }}</dd>
<dt>
<router-link :to="item.path">
<div>{{item.title}}</div>
<div>
{{ item.title }}
<span class="title-tag" v-if="item.frontmatter.titleTag">
{{ item.frontmatter.titleTag }}
</span>
</div>
</router-link>
<span>{{getDate(item)}}</span>
<span class="date">{{ getDate(item) }}</span>
</dt>
</dl>
<dl>
<dd></dd>
<dt>
<router-link
:to="moreArticle || '/archives/'"
class="more"
>更多文章></router-link>
<router-link :to="moreArticle || '/archives/'" class="more"
>更多文章></router-link
>
</dt>
</dl>
</div>
@ -44,39 +44,39 @@ export default {
},
moreArticle: String
},
data () {
data() {
return {
posts: [],
currentPath: ''
}
},
created () {
created() {
this.posts = this.$site.pages
this.currentPath = this.$page.path
},
computed: {
topPublishPosts () {
topPublishPosts() {
return this.$sortPostsByDate ? this.$sortPostsByDate.filter(post => {
const { path } = post
return path !== this.currentPath
}).slice(0, this.length) : []
},
isShowArticle () {
isShowArticle() {
const { frontmatter } = this.$page
return !(frontmatter.article !== false)
}
},
methods: {
getNum (index) {
getNum(index) {
return index < 9 ? '0' + (index + 1) : index + 1
},
getDate (item) {
getDate(item) {
return item.frontmatter.date ? item.frontmatter.date.split(" ")[0].slice(5, 10) : ''
}
},
watch: {
$route () {
$route() {
this.currentPath = this.$page.path
}
}
@ -137,11 +137,22 @@ export default {
display -webkit-box
-webkit-line-clamp 2
-webkit-box-orient vertical
.title-tag
// height 1.1rem
// line-height 1.1rem
border 1px solid $activeColor
color $activeColor
font-size 0.8rem
padding 0 0.35rem
border-radius 0.2rem
margin-left 0rem
transform translate(0, -0.05rem)
display inline-block
&:hover
text-decoration underline
&.more
color $accentColor
span
.date
width 50px
margin-right 15px
color #999

View File

@ -35,13 +35,13 @@ export default ({
// 修复ISO8601时间格式为普通时间格式
function repairUTCDate (date) {
function repairUTCDate(date) {
if (!(date instanceof Date)) {
date = new Date(date)
}
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth() + 1)}-${zero(date.getUTCDate())} ${zero(date.getUTCHours())}:${zero(date.getUTCMinutes())}:${zero(date.getUTCSeconds())}`;
}
// 小于10补0
function zero (d) {
function zero(d) {
return d.toString().padStart(2, '0')
}

View File

@ -31,7 +31,7 @@ module.exports = (options, ctx) => {
const sidebarData = getSidebarData(sourceDir, collapsable)
if (sidebarData) {
themeConfig.sidebar = sidebarData
log(chalk.blue('tip ') + chalk.green('add sidebar data. 侧边栏数据成功生成。'))
log(chalk.blue('tip ') + chalk.green('add sidebar data. 成功生成侧边栏数据。'))
} else {
themeConfig.sidebar = 'auto'
log(chalk.yellow('warning: fail to add sidebar data, switch to "auto". 未能添加侧边栏数据将切换为“auto”。'))
@ -70,7 +70,7 @@ module.exports = (options, ctx) => {
const enableSmoothScroll = themeConfig.smoothScroll === true
return {
alias () {
alias() {
return {
'@AlgoliaSearchBox': isAlgoliaSearch
? path.resolve(__dirname, 'components/AlgoliaSearchBox.vue')
@ -173,7 +173,7 @@ module.exports = (options, ctx) => {
// 渲染md容器的卡片列表
function renderCardList (tokens, idx, type) {
function renderCardList(tokens, idx, type) {
const END_TYPE = `container_${type}_close`,
_tokens$idx = tokens[idx],
nesting = _tokens$idx.nesting,
@ -197,9 +197,15 @@ function renderCardList (tokens, idx, type) {
if (yamlStr) { // 正确解析出yaml字符串后
const dataObj = yaml.safeLoad(yamlStr) // 将yaml字符串解析成js对象
let dataList = []
let config = {}
if (dataObj) { // 正确解析出数据对象
dataList = Array.isArray(dataObj) ? dataObj : dataObj.list
if (Array.isArray(dataObj)) {
dataList = dataObj
} else {
config = dataObj.config
dataList = dataObj.data
}
}
if (dataList && dataList.length) { // 有列表数据
@ -212,9 +218,9 @@ function renderCardList (tokens, idx, type) {
let listDOM = ''
if (type === CARD_LIST) { // 普通卡片列表
listDOM = getCardListDOM(dataList, row)
listDOM = getCardListDOM(dataList, row, config)
} else if (type === CARD_IMG_LIST) { // 卡片图片列表
listDOM = getCardImgListDOM(dataList, row)
listDOM = getCardImgListDOM(dataList, row, config)
}
return `<div class="${type}Container"><div class="card-list">${listDOM}</div>`
@ -227,11 +233,12 @@ function renderCardList (tokens, idx, type) {
// 将数据解析成DOM结构 - 普通卡片列表
function getCardListDOM (dataList, row) {
function getCardListDOM(dataList, row, config) {
const { target = '_blank' } = config
let listDOM = ''
dataList.forEach(item => {
listDOM += `
<${item.link ? 'a href="' + item.link + '" target="_blank"' : 'span'} class="card-item ${row ? 'row-' + row : ''}"
<${item.link ? 'a href="' + item.link + '" target="' + target + '"' : 'span'} class="card-item ${row ? 'row-' + row : ''}"
style="${item.bgColor ? 'background-color:' + item.bgColor + ';--randomColor:' + item.bgColor + ';' : '--randomColor: var(--bodyBg);'}${item.textColor ? 'color:' + item.textColor + ';' : ''}"
>
${item.avatar ? '<img src="' + withBase(item.avatar) + '" class="no-zoom">' : ''}
@ -247,18 +254,20 @@ function getCardListDOM (dataList, row) {
// 将数据解析成DOM结构 - 图文卡片列表
function getCardImgListDOM (dataList, row) {
function getCardImgListDOM(dataList, row, config) {
const { imgHeight = 'auto', objectFit = 'cover', lineClamp = 1, target = '_blank' } = config
let listDOM = ''
dataList.forEach(item => {
listDOM += `
<div class="card-item ${row ? 'row-' + row : ''}" >
<a href="${item.link}" target="_blank">
<div class="box-img">
<img src="${withBase(item.img)}" class="no-zoom">
<a href="${item.link}" target="${target}">
<div class="box-img" style="height: ${imgHeight}">
<img src="${withBase(item.img)}" class="no-zoom" style="object-fit: ${objectFit}">
</div>
<div class="box-info">
<p class="name">${item.name}</p>
${item.desc ? `<p class="desc">${item.desc}</p>` : ''}
${item.desc ? `<p class="desc" style="line-clamp: ${lineClamp}">${item.desc}</p>` : ''}
</div>
${item.avatar || item.author ? `<div class="box-footer">
@ -273,7 +282,7 @@ function getCardImgListDOM (dataList, row) {
}
// 添加base路径
function withBase (path) {
function withBase(path) {
if (base && path.charAt(0) === '/') {
return base + path.slice(1);
} else {

View File

@ -13,23 +13,6 @@
"type": "git",
"url": "git+https://github.com/xugaoyi/vuepress-theme-vdoing.git"
},
"dependencies": {
"@better-scroll/core": "^2.0.0-beta.6",
"@better-scroll/slide": "^2.0.0-beta.6",
"@vuepress/plugin-active-header-links": "^1.2.0",
"@vuepress/plugin-nprogress": "^1.2.0",
"@vuepress/plugin-search": "^1.2.0",
"chalk": "^4.0.0",
"json2yaml": "^1.1.0",
"js-yaml": "^3.13.1",
"docsearch.js": "^2.5.2",
"good-storage": "^1.1.1",
"lodash": "^4.17.15",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"vuepress-plugin-container": "^2.0.2",
"vuepress-plugin-smooth-scroll": "^0.0.3"
},
"keywords": [
"documentation",
"vue",
@ -40,8 +23,30 @@
],
"license": "MIT",
"main": "index.js",
"maintainers": [{
"name": "Evan xu",
"email": "894072666@qq.com"
}]
"maintainers": [
{
"name": "Evan xu",
"email": "894072666@qq.com"
}
],
"dependencies": {
"@better-scroll/core": "^2.0.0-beta.6",
"@better-scroll/slide": "^2.0.0-beta.6",
"@vuepress/plugin-active-header-links": "^1.2.0",
"@vuepress/plugin-nprogress": "^1.2.0",
"@vuepress/plugin-search": "^1.2.0",
"chalk": "^4.0.0",
"docsearch.js": "^2.5.2",
"good-storage": "^1.1.1",
"js-yaml": "^3.13.1",
"json2yaml": "^1.1.0",
"lodash": "^4.17.15",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"vuepress-plugin-container": "^2.0.2",
"vuepress-plugin-smooth-scroll": "^0.0.3"
},
"devDependencies": {
"@vuepress/types": "^1.9.5"
}
}

View File

@ -114,11 +114,11 @@ h1, h2, h3, h4, h5, h6
.box-img
overflow hidden
position relative
background #000
background #eee
img
display block
width 100%
height auto
height 100%
transition: all .3s
// &:hover
// img
@ -139,6 +139,11 @@ h1, h2, h3, h4, h5, h6
opacity .8
font-size: .9rem
line-height: 1.1rem
overflow: hidden;
white-space: normal;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
.box-footer
overflow hidden
padding: .8rem 1rem

View File

@ -0,0 +1,42 @@
import { DefaultThemeConfig } from '@vuepress/types'
// vdoing主题配置类型
export interface VdoingThemeConfig extends DefaultThemeConfig {
/**
* . Enable classification
* @default true
*/
category?: boolean;
/**
* . Enable tag
* @default true
*/
tag?: boolean;
/**
* . Enable archive
* @default true
*/
archive?: boolean;
/**
* _posts文件夹的文章
* @default '随笔'
*/
categoryText?: string;
/**
* body背景大图链接 string | string[], 15
* @default ''
*/
bodyBgImg?: string | string[];
/**
* body背景图透明度 0.1 ~ 1.0
* @default 0.5
*/
bodyBgImgOpacity?: 0.1 | 0.2 | 0.3 | 0.4 | 0.5 | 0.6 | 0.7 | 0.8 | 0.9 | 1;
}