添加批量添加和修改front matter工具

This commit is contained in:
xugaoyi 2020-04-17 16:34:25 +08:00
parent eca7509e45
commit b70955eeab
96 changed files with 1002 additions and 899 deletions

View File

@ -77,6 +77,8 @@
[palette.styl主题调色板使用说明](https://github.com/xugaoyi/vuepress-theme-vdoing/issues/345)
8. 专为主题定制的辅助工具: [批量修改front matter工具](https://github.com/xugaoyi/vuepress-theme-vdoing/issues/351)
## Start
```bash

View File

@ -2,7 +2,6 @@
pageComponent:
name: Timeline # 组件名Timeline => 时间轴组件
# data:
# tagBgColor: ['#11a8cd', '#F8B26A', '#67CC86', '#E15B64', '#F47E60', '#849B87'] # 注意,这里定义数组建议使用中括号的形式,避免把#井号解析为注释
# slogan: '只争朝夕,不负韶华!( •̀ ω •́ )✧'
title: 时间轴

View File

@ -2,6 +2,8 @@
title: ECMAScript 6 简介
date: 2020-01-12 15:45:35
permalink: /pages/f344d070a1031ef7
author:
name: 阮一峰
---
> 说明:本章内容为博主在原教程基础上添加自己的学习笔记,来源<http://es6.ruanyifeng.com/>,教程版权归原作者所有。

View File

@ -2,6 +2,8 @@
title: let 和 const 命令
date: 2020-02-09 16:00:29
permalink: /pages/c1edd70a6b7c7872
author:
name: 阮一峰
---
# let 和 const 命令

View File

@ -2,6 +2,8 @@
title: 变量的解构赋值
date: 2020-02-09 16:00:29
permalink: /pages/b1ab10a62f7564da
author:
name: 阮一峰
---
# 变量的解构赋值

View File

@ -2,6 +2,8 @@
title: 字符串的扩展
date: 2020-02-09 16:00:29
permalink: /pages/ca89eca8adeba5f4
author:
name: 阮一峰
---
# 字符串的扩展

View File

@ -2,6 +2,8 @@
title: 字符串的新增方法
date: 2020-02-09 16:00:29
permalink: /pages/a650b4a0ebfc9350
author:
name: 阮一峰
---
# 字符串的新增方法

View File

@ -2,6 +2,8 @@
title: 正则的扩展
date: 2020-02-09 16:00:29
permalink: /pages/0473261a6ab0ee8c
author:
name: 阮一峰
---
# 正则的扩展

View File

@ -2,6 +2,8 @@
title: 数值的扩展
date: 2020-02-09 16:00:29
permalink: /pages/5dfea9a0f2d1a392
author:
name: 阮一峰
---
# 数值的扩展

View File

@ -2,6 +2,8 @@
title: 函数的扩展
date: 2020-02-09 16:00:29
permalink: /pages/8ed309d668b20264
author:
name: 阮一峰
---
# 函数的扩展

View File

@ -2,6 +2,8 @@
title: 数组的扩展
date: 2020-02-09 16:00:29
permalink: /pages/e34009d60d8bc4b2
author:
name: 阮一峰
---
# 数组的扩展

View File

@ -2,6 +2,8 @@
title: 对象的扩展
date: 2020-02-09 16:00:29
permalink: /pages/b5e3e0a0ff6e9c25
author:
name: 阮一峰
---
# 对象的扩展

View File

@ -2,6 +2,8 @@
title: 对象的新增方法
date: 2020-02-09 16:00:29
permalink: /pages/e85e68947502cf90
author:
name: 阮一峰
---
# 对象的新增方法

View File

@ -2,6 +2,8 @@
title: Symbol
date: 2020-02-09 16:00:29
permalink: /pages/02c86eb2792f3262
author:
name: 阮一峰
---
# Symbol

View File

@ -2,6 +2,8 @@
title: Set 和 Map 数据结构
date: 2020-02-09 16:00:29
permalink: /pages/0c21dae358fca16b
author:
name: 阮一峰
---
# Set 和 Map 数据结构

View File

@ -2,6 +2,8 @@
title: Proxy
date: 2020-02-09 16:00:29
permalink: /pages/f56ec2ab97d60483
author:
name: 阮一峰
---
# Proxy

View File

@ -2,6 +2,8 @@
title: Reflect
date: 2020-02-09 16:00:29
permalink: /pages/74de3e45e4491e95
author:
name: 阮一峰
---
# Reflect

View File

@ -2,6 +2,8 @@
title: Promise 对象
date: 2020-02-09 16:00:29
permalink: /pages/2810ae8985e9bd52
author:
name: 阮一峰
---
# Promise 对象

View File

@ -2,6 +2,8 @@
title: Iterator 和 for-of 循环
date: 2020-02-09 16:00:29
permalink: /pages/48df907ad3570f3d
author:
name: 阮一峰
---
# Iterator 和 for...of 循环

View File

@ -2,6 +2,8 @@
title: Generator 函数的语法
date: 2020-02-09 16:00:29
permalink: /pages/718b48ed9ce0adce
author:
name: 阮一峰
---
# Generator 函数的语法

View File

@ -2,6 +2,8 @@
title: Generator 函数的异步应用
date: 2020-02-09 16:00:29
permalink: /pages/75af7031eb66847b
author:
name: 阮一峰
---
# Generator 函数的异步应用

View File

@ -2,6 +2,8 @@
title: async 函数
date: 2020-02-09 16:00:29
permalink: /pages/3777253e65bac487
author:
name: 阮一峰
---
# async 函数

View File

@ -2,6 +2,8 @@
title: Class 的基本语法
date: 2020-02-09 16:00:29
permalink: /pages/e831e1593c82bbe0
author:
name: 阮一峰
---
# Class 的基本语法

View File

@ -2,6 +2,8 @@
title: Class 的继承
date: 2020-02-09 16:00:29
permalink: /pages/83f8c3a0cd87dd83
author:
name: 阮一峰
---
# Class 的继承

View File

@ -2,6 +2,8 @@
title: Module 的语法
date: 2020-02-09 16:00:29
permalink: /pages/efe2fb04eb8ac5fb
author:
name: 阮一峰
---
# Module 的语法

View File

@ -2,6 +2,8 @@
title: Module 的加载实现
date: 2020-02-09 16:00:29
permalink: /pages/a79ca2e64ceae213
author:
name: 阮一峰
---
# Module 的加载实现

View File

@ -2,6 +2,8 @@
title: 编程风格
date: 2020-02-09 16:00:29
permalink: /pages/984bf549204bb266
author:
name: 阮一峰
---
# 编程风格

View File

@ -2,6 +2,8 @@
title: 读懂 ECMAScript 规格
date: 2020-02-09 16:00:29
permalink: /pages/32c35f7651d6e58e
author:
name: 阮一峰
---
# 读懂 ECMAScript 规格

View File

@ -2,6 +2,8 @@
title: 异步遍历器
date: 2020-02-09 16:00:29
permalink: /pages/16121351be68691b
author:
name: 阮一峰
---
# 异步遍历器

View File

@ -2,6 +2,8 @@
title: ArrayBuffer
date: 2020-02-09 16:00:29
permalink: /pages/a2ba314746bfdbdd
author:
name: 阮一峰
---
# ArrayBuffer

View File

@ -2,6 +2,8 @@
title: 最新提案
date: 2020-02-09 16:00:30
permalink: /pages/7188882b8d65af1b
author:
name: 阮一峰
---
# 最新提案

View File

@ -2,6 +2,8 @@
title: 装饰器
date: 2020-02-09 16:00:30
permalink: /pages/e97bc1e5626b082c
author:
name: 阮一峰
---
# 装饰器

View File

@ -2,6 +2,8 @@
title: 函数式编程
date: 2020-02-09 16:00:30
permalink: /pages/1cf50330655efc69
author:
name: 阮一峰
---
# 函数式编程

View File

@ -2,6 +2,8 @@
title: Mixin
date: 2020-02-09 16:00:30
permalink: /pages/6a8e2dc558da1b39
author:
name: 阮一峰
---
# Mixin

View File

@ -2,6 +2,8 @@
title: SIMD
date: 2020-02-09 16:00:30
permalink: /pages/8e8f80f69b775a56
author:
name: 阮一峰
---
# SIMD

View File

@ -2,6 +2,8 @@
title: 参考链接
date: 2020-02-09 16:00:30
permalink: /pages/ea6f3b870f6dab69
author:
name: 阮一峰
---
# 参考链接

View File

@ -2,6 +2,8 @@
title: 简介
date: 2020-01-05 10:15:07
permalink: /pages/e05dce83e5129785
author:
name: HuangYi
---
# 简介

View File

@ -2,6 +2,8 @@
title: 安装 TypeScript
date: 2020-01-05 10:15:07
permalink: /pages/064e0f7b6b6142c8
author:
name: HuangYi
---
# 安装 TypeScript

View File

@ -2,6 +2,8 @@
title: 编写第一个 TypeScript 程序
date: 2020-01-05 10:15:07
permalink: /pages/c85249f40e7a3517
author:
name: HuangYi
---
# 编写第一个 TypeScript 程序

View File

@ -2,6 +2,8 @@
title: 基础类型
date: 2020-01-05 10:17:47
permalink: /pages/28672e2743bbc3a7
author:
name: HuangYi
---
# 基础类型

View File

@ -2,6 +2,8 @@
title: 变量声明
date: 2020-01-05 10:17:47
permalink: /pages/54add7f5cf78088e
author:
name: HuangYi
---
# 变量声明

View File

@ -2,6 +2,8 @@
title: 接口
date: 2020-01-05 10:17:47
permalink: /pages/54ea89b497ec3bb3
author:
name: HuangYi
---
# 接口

View File

@ -2,6 +2,8 @@
title: 类
date: 2020-01-05 10:17:47
permalink: /pages/fad060bd9a8bfac6
author:
name: HuangYi
---
# 类

View File

@ -2,6 +2,8 @@
title: 函数
date: 2020-01-05 10:17:47
permalink: /pages/870a51ba2a9edfad
author:
name: HuangYi
---
# 函数

View File

@ -2,6 +2,8 @@
title: 泛型
date: 2020-01-05 10:17:47
permalink: /pages/8045759ec4ad3c01
author:
name: HuangYi
---
# 泛型

View File

@ -2,6 +2,8 @@
title: 类型推断
date: 2020-01-05 10:17:47
permalink: /pages/7279420c899c505d
author:
name: HuangYi
---
# 类型推断

View File

@ -2,6 +2,8 @@
title: 高级类型
date: 2020-01-05 10:17:47
permalink: /pages/3fb6c2f52ab398e3
author:
name: HuangYi
---
# 高级类型

View File

@ -2,6 +2,8 @@
title: 需求分析
date: 2020-01-05 10:56:02
permalink: /pages/195af93fcc871b8b
author:
name: HuangYi
---
# 需求分析

View File

@ -2,6 +2,8 @@
title: 初始化项目
date: 2020-01-05 10:56:02
permalink: /pages/6e11ac76475a2b3e
author:
name: HuangYi
---
# 初始化项目

View File

@ -2,6 +2,8 @@
title: 编写基础请求代码
date: 2020-01-05 10:56:02
permalink: /pages/acfe1e0b401fa984
author:
name: HuangYi
---
# 编写基础请求代码

View File

@ -2,6 +2,8 @@
title: 处理请求 url 参数
date: 2020-01-05 10:56:02
permalink: /pages/1313dae575f6dddf
author:
name: HuangYi
---
# 处理请求 url 参数

View File

@ -2,6 +2,8 @@
title: 处理请求 body 数据
date: 2020-01-05 10:56:02
permalink: /pages/887cd0918e2543d8
author:
name: HuangYi
---
# 处理请求 body 数据

View File

@ -2,6 +2,8 @@
title: 处理请求 header
date: 2020-01-05 10:56:02
permalink: /pages/35c0ec1bb0b0faaf
author:
name: HuangYi
---
# 处理请求 header

View File

@ -2,6 +2,8 @@
title: 获取响应数据
date: 2020-01-05 10:56:02
permalink: /pages/a57debe141e1e4f4
author:
name: HuangYi
---
# 获取响应数据

View File

@ -2,6 +2,8 @@
title: 处理响应 header
date: 2020-01-05 10:56:02
permalink: /pages/927161662ca32c24
author:
name: HuangYi
---
# 处理响应 header

View File

@ -2,6 +2,8 @@
title: 处理响应 data
date: 2020-01-05 10:56:02
permalink: /pages/922cb4268499dc3f
author:
name: HuangYi
---
# 处理响应 data

View File

@ -2,6 +2,8 @@
title: 错误处理
date: 2020-01-05 10:56:02
permalink: /pages/6a8bef7b98dfdcf9
author:
name: HuangYi
---
# 错误处理

View File

@ -2,6 +2,8 @@
title: 错误信息增强
date: 2020-01-05 10:56:02
permalink: /pages/22d581d8c2860b8a
author:
name: HuangYi
---
# 错误信息增强

View File

@ -2,6 +2,8 @@
title: 扩展接口
date: 2020-01-05 10:56:02
permalink: /pages/034e320f4af88bd4
author:
name: HuangYi
---
# 扩展接口

View File

@ -2,6 +2,8 @@
title: axios 函数重载
date: 2020-01-05 10:56:02
permalink: /pages/8af227eae851ec97
author:
name: HuangYi
---
# axios 函数重载

View File

@ -2,6 +2,8 @@
title: 响应数据支持泛型
date: 2020-01-05 10:56:02
permalink: /pages/c4489d0bab02cc0c
author:
name: HuangYi
---
# 响应数据支持泛型

View File

@ -2,6 +2,8 @@
title: 拦截器设计与实现
date: 2020-01-05 10:56:02
permalink: /pages/70651900f022f586
author:
name: HuangYi
---
拦截器设计与实现

View File

@ -2,6 +2,8 @@
title: 合并配置的设计与实现
date: 2020-01-05 10:56:02
permalink: /pages/937e4de6b81edeca
author:
name: HuangYi
---
# 合并配置的设计与实现

View File

@ -2,6 +2,8 @@
title: 请求和响应配置化
date: 2020-01-05 10:56:02
permalink: /pages/f5b627bfebba87fc
author:
name: HuangYi
---
# 请求和响应配置化

View File

@ -2,6 +2,8 @@
title: 扩展 create 静态接口
date: 2020-01-05 10:56:02
permalink: /pages/7b49658c26f613bf
author:
name: HuangYi
---
# 扩展 axios.create 静态接口

View File

@ -2,6 +2,8 @@
title: 取消功能的设计与实现
date: 2020-01-05 10:56:02
permalink: /pages/fdc6da5372397430
author:
name: HuangYi
---
# 取消功能的设计与实现

View File

@ -2,6 +2,8 @@
title: withCredentials
date: 2020-01-05 10:56:02
permalink: /pages/5dce43eba796a2ab
author:
name: HuangYi
---
# withCredentials

View File

@ -2,6 +2,8 @@
title: XSRF 防御
date: 2020-01-05 10:56:02
permalink: /pages/390cb70e2b619449
author:
name: HuangYi
---
# XSRF 防御

View File

@ -2,6 +2,8 @@
title: 上传和下载的进度监控
date: 2020-01-05 10:56:02
permalink: /pages/1376fd897809036e
author:
name: HuangYi
---
# 上传和下载的进度监控

View File

@ -2,6 +2,8 @@
title: HTTP 授权
date: 2020-01-05 10:56:02
permalink: /pages/89cd6496c23159ae
author:
name: HuangYi
---
# HTTP 授权

View File

@ -2,6 +2,8 @@
title: 自定义合法状态码
date: 2020-01-05 10:56:02
permalink: /pages/40b41ce8e8159567
author:
name: HuangYi
---
# 自定义合法状态码

View File

@ -2,6 +2,8 @@
title: 自定义参数序列化
date: 2020-01-05 10:56:02
permalink: /pages/7753b8141663e54a
author:
name: HuangYi
---
# 自定义参数序列化

View File

@ -2,6 +2,8 @@
title: baseURL
date: 2020-01-05 10:56:02
permalink: /pages/0b9f2ee2b4dbb728
author:
name: HuangYi
---
# baseURL

View File

@ -2,6 +2,8 @@
title: 静态方法扩展
date: 2020-01-05 10:56:02
permalink: /pages/c26b053540a7dafa
author:
name: HuangYi
---
# 静态方法扩展

View File

@ -2,6 +2,8 @@
title: 前言
date: 2020-01-05 10:56:02
permalink: /pages/df36888424843793
author:
name: HuangYi
---
# 前言

View File

@ -2,6 +2,8 @@
title: Jest 安装和配置
date: 2020-01-05 10:56:02
permalink: /pages/bf5c625a35757b37
author:
name: HuangYi
---
# Jest 安装和配置

View File

@ -2,6 +2,8 @@
title: 辅助模块单元测试
date: 2020-01-05 10:56:02
permalink: /pages/13f147a9b355c4c1
author:
name: HuangYi
---
# 辅助模块单元测试

View File

@ -2,6 +2,8 @@
title: 请求模块单元测试
date: 2020-01-05 10:56:02
permalink: /pages/e1d15dec8634e6b5
author:
name: HuangYi
---
# 请求模块单元测试

View File

@ -2,6 +2,8 @@
title: headers 模块单元测试
date: 2020-01-05 10:56:02
permalink: /pages/ddd86ec39b5dfe33
author:
name: HuangYi
---
# headers 模块单元测试

View File

@ -2,6 +2,8 @@
title: Axios 实例模块单元测试
date: 2020-01-05 10:56:02
permalink: /pages/2eac7a0a0d644c15
author:
name: HuangYi
---
# Axios 实例模块单元测试

View File

@ -2,6 +2,8 @@
title: 拦截器模块单元测试
date: 2020-01-05 10:56:02
permalink: /pages/97de6fd6293a2c6e
author:
name: HuangYi
---
# 拦截器模块单元测试

View File

@ -2,6 +2,8 @@
title: mergeConfig 模块单元测试
date: 2020-01-05 10:56:02
permalink: /pages/cdf59840306f9e81
author:
name: HuangYi
---
# mergeConfig 模块单元测试

View File

@ -2,6 +2,8 @@
title: 请求取消模块单元测试
date: 2020-01-05 10:56:02
permalink: /pages/6fa16aee29527032
author:
name: HuangYi
---
# 请求取消模块单元测试

View File

@ -2,6 +2,8 @@
title: 剩余模块单元测试
date: 2020-01-05 10:56:02
permalink: /pages/9572134781ba6a25
author:
name: HuangYi
---
# 剩余模块单元测试

View File

@ -2,6 +2,8 @@
title: ts-axios 编译与发布
date: 2020-01-05 10:56:02
permalink: /pages/3e5d5a45ad50f198
author:
name: HuangYi
---
# ts-axios 编译与发布

View File

@ -2,6 +2,8 @@
title: 引用 ts-axios 库
date: 2020-01-05 10:56:02
permalink: /pages/c6bdbd5bd60adf5a
author:
name: HuangYi
---
# 引用 ts-axios 库

View File

@ -13,6 +13,7 @@
"devDependencies": {
"@vuepress/plugin-back-to-top": "^1.2.0",
"ejs": "^3.0.1",
"inquirer": "^7.1.0",
"json2yaml": "^1.1.0",
"md5.js": "^1.3.5",
"moment": "^2.24.0",

View File

@ -1,20 +1,21 @@
<template>
<div class="i-body" :style="footerBgImg && `background-image: url(${footerBgImg})`">
<div class="banner" :style="data.bgImg && `background: url(${$withBase(data.bgImg)}) center center / cover no-repeat`">
<main class="home" :style="!data.features && `padding-top: 7rem`">
<!-- banner块 s -->
<div class="banner" :style="homeData.bgImg && `background: url(${$withBase(homeData.bgImg)}) center center / cover no-repeat`">
<div class="banner-conent" :style="!homeData.features && `padding-top: 7rem`">
<header class="hero">
<img v-if="data.heroImage" :src="$withBase(data.heroImage)" :alt="data.heroAlt || 'hero'" />
<h1 v-if="data.heroText !== null" id="main-title">{{ data.heroText || $title || 'Hello' }}</h1>
<p class="description">{{ data.tagline || $description || 'Welcome to your VuePress site' }}</p>
<p class="action" v-if="data.actionText && data.actionLink">
<img v-if="homeData.heroImage" :src="$withBase(homeData.heroImage)" :alt="homeData.heroAlt || 'hero'" />
<h1 v-if="homeData.heroText !== null" id="main-title">{{ homeData.heroText || $title || 'Hello' }}</h1>
<p class="description">{{ homeData.tagline || $description || 'Welcome to your VuePress site' }}</p>
<p class="action" v-if="homeData.actionText && homeData.actionLink">
<NavLink class="action-button" :item="actionLink" />
</p>
</header>
<!-- PC端features块 s -->
<div class="features" v-if="data.features && data.features.length && !isMQMobile">
<div class="feature" v-for="(feature, index) in data.features" :key="index">
<div class="features" v-if="homeData.features && homeData.features.length && !isMQMobile">
<div class="feature" v-for="(feature, index) in homeData.features" :key="index">
<router-link :to="feature.link">
<img class="image_title" :src="$withBase(feature.imgUrl)" :alt="feature.title" />
<h2>{{ feature.title }}</h2>
@ -23,14 +24,14 @@
</div>
</div>
<!-- PC端features块 e -->
</main>
</div>
<!-- 移动端slide s -->
<div class="slide-banner" v-if="data.features && data.features.length" v-show="isMQMobile">
<!-- 移动端features块 s -->
<div class="slide-banner" v-if="homeData.features && homeData.features.length" v-show="isMQMobile">
<div class="banner-wrapper">
<div class="slide-banner-scroll" ref="slide">
<div class="slide-banner-wrapper">
<div class="slide-item" v-for="(feature, index) in data.features" :key="index">
<div class="slide-item" v-for="(feature, index) in homeData.features" :key="index">
<router-link :to="feature.link">
<img class="image_title" :src="$withBase(feature.imgUrl)" :alt="feature.title" />
<h2>{{ feature.title }}</h2>
@ -42,51 +43,57 @@
<div class="docs-wrapper">
<span
class="doc"
v-for="(item, index) in data.features.length"
v-for="(item, index) in homeData.features.length"
:key="index"
:class="{'active': currentPageIndex === index}"></span>
</div>
</div>
</div>
<!-- 移动端slide e -->
<!-- 移动端features块 e -->
</div>
<!-- banner块 e -->
<div class="main-wrapper">
<main class="home home-content" aria-labelledby="main-title">
<UpdateArticle
pageMark="home"
:length="updateBarConfig && updateBarConfig.onHome && updateBarConfig.onHome.length || 5"
:moreArticle="updateBarConfig && updateBarConfig.moreArticle"
v-if="isShowUpdateBar"
/>
<Content class="theme-vdoing-content custom" />
</main>
<aside class="info-wrapper" v-if="blogger">
<div class="avatar">
<img :src="blogger.avatar" alt="头像">
</div>
<div class="icons" v-if="blogger.social">
<a
:href="item.link"
:title="item.title"
:class="['iconfont', item.iconClass]"
v-for="(item, index) in blogger.social.icons"
:key="index"
:style="{width: 100/blogger.social.icons.length + '%'}"
target="_blank"
>
</a>
</div>
<div class="blogger">
<span class="name">{{blogger.name}}</span>
<span class="slogan">
{{blogger.slogan}}
</span>
</div>
</aside>
<div class="main-left">
<PostList/>
<Content class="theme-vdoing-content custom card-box" />
<!-- <main class="home home-content" aria-labelledby="main-title">
<UpdateArticle
pageMark="home"
:length="updateBarConfig && updateBarConfig.onHome && updateBarConfig.onHome.length || 5"
:moreArticle="updateBarConfig && updateBarConfig.moreArticle"
v-if="isShowUpdateBar"
/>
</main> -->
</div>
<div class="main-right">
<aside class="blogger-wrapper card-box" v-if="blogger">
<div class="avatar">
<img :src="blogger.avatar" alt="头像" title="我好看吗">
</div>
<div class="icons" v-if="blogger.social">
<a
:href="item.link"
:title="item.title"
:class="['iconfont', item.iconClass]"
v-for="(item, index) in blogger.social.icons"
:key="index"
:style="{width: 100/blogger.social.icons.length + '%'}"
target="_blank"
>
</a>
</div>
<div class="blogger">
<span class="name">{{blogger.name}}</span>
<span class="slogan">
{{blogger.slogan}}
</span>
</div>
</aside>
</div>
</div>
<Footer />
@ -94,13 +101,16 @@
</template>
<script>
import NavLink from "@theme/components/NavLink.vue";
import NavLink from "@theme/components/NavLink";
import BScroll from "@better-scroll/core"
import Slide from "@better-scroll/slide"
import UpdateArticle from './UpdateArticle.vue'
import Footer from './Footer.vue'
import UpdateArticle from './UpdateArticle'
import PostList from './PostList'
import Footer from './Footer'
const MOBILE_DESKTOP_BREAKPOINT = 720 // refer to config.styl
BScroll.use(Slide)
export default {
data(){
return {
@ -161,6 +171,7 @@ export default {
probeType: 2,
preventDefault: false
})
// user touches the slide area
this.slide.on('beforeScrollStart', () => {
clearTimeout(this.playTimer)
@ -181,10 +192,15 @@ export default {
}, 4000)
}
},
components: { NavLink, UpdateArticle, Footer },
components: { NavLink, UpdateArticle, PostList, Footer },
computed: {
data() {
return this.$page.frontmatter;
homeData() {
return {
...this.$page.frontmatter,
base: this.$site.base
}
},
isShowUpdateBar() {
return this.updateBarConfig && this.updateBarConfig.onHome && this.updateBarConfig.onHome.isShow === false ? false : true
@ -197,8 +213,8 @@ export default {
},
actionLink() {
return {
link: this.data.actionLink,
text: this.data.actionText
link: this.homeData.actionLink,
text: this.homeData.actionText
};
}
}
@ -206,249 +222,248 @@ export default {
</script>
<style lang="stylus">
//
.slide-banner
margin-top: 2rem;
.banner-wrapper
position relative
.slide-banner-scroll
min-height 1px
overflow hidden
.slide-banner-wrapper
height 300px
.slide-item
display inline-block
height 300px
width 100%
text-align center
.image_title
width: 10rem;
height: 10rem;
h2
font-size: 1.1rem;
color: #fff;
font-weight: 500;
border-bottom: none;
padding-bottom: 0;
p
color: #b0b6be;
.docs-wrapper
position absolute
bottom 25px
left 50%
transform translateX(-50%)
.doc
display inline-block
margin 0 4px
width 8px
height 8px
border-radius 50%
background #2F455A
&.active
background #517EA9
.i-body
background bottom no-repeat
// background-color var(--homeBg)
background-color rgba(220,220,220,0.1)
overflow hidden
.banner
width 100%
min-height 450px
background rgb(40,40,45)
color #fff
position relative
overflow hidden
background-image url(../images/bg-line.png)
background-size 35px 35px
.home
background none
.banner
width 100%
min-height 450px
margin-top $navbarHeight
background rgb(40,40,45)
color #fff
position relative
z-index 1
.hero
h1
font-size 3.5rem
margin: 3.5rem auto 1.8rem auto
.description
font-size 1.2rem
color #fff
.features
border-top none
.feature
h2
font-size 1.3rem
color #fff
p
color #fff
opacity 0.8
// color #B0B6BE
body .main-wrapper
margin 2rem auto
max-width 1080px
position relative
display flex
>*
border-radius 5px
background var(--bg)
box-shadow 0 1px 2px 0 rgba(0,0,30,.1), 0 2px 4px 0 rgba(0,0,0,.1)
.home-content
padding 1rem 1.5rem 0
flex 1
.info-wrapper
width 260px
padding 15px
height auto
margin-left 10px
display inline-table
.avatar
width 260px
height 260px
overflow hidden
background-image url(../images/bg-line.png)
background-size 35px 35px
.banner-conent
max-width $homePageWidth
margin 0px auto
position relative
z-index 1
overflow hidden
img
width 100%
height 100%
border-radius 3px
.icons
border 1px solid var(--borderColor)
height 40px
line-height 40px
a
font-size 20px
width 33%
color var(--textColor)
display block
float left
.hero
text-align center
opacity .8
&:hover
color $accentColor
.blogger
margin 15px 0 10px 0
.name
font-size 24px
display: block
margin-bottom 10px
.slogan
color var(--textColor)
.home
padding $navbarHeight 2rem 0
max-width 1080px
margin 0px auto
display block
.hero
text-align center
img
max-width 100%
max-height 192px
display block
margin 2rem auto 1.5rem
h1
font-size 3rem
h1, .description, .action
margin 1.8rem auto
.description
max-width 40rem
font-size 1.4rem
line-height 1.3
color var(--textLightenColor)
.action-button
display inline-block
font-size 1.2rem
color #fff
background-color $accentColor
padding 0.8rem 1.6rem
border-radius 4px
transition background-color 0.1s ease
box-sizing border-box
border-bottom 1px solid darken($accentColor, 10%)
&:hover
background-color lighten($accentColor, 10%)
.features
border-top 1px solid var(--borderColor)
padding 2rem 0
margin-top 2.5rem
margin-top 3rem
img
max-width 100%
max-height 192px
display block
margin 2rem auto 1.5rem
h1
margin 0
font-size 3.5rem
.description, .action
margin 1.5rem auto
.description
max-width 40rem
font-size 1.2rem
line-height 1.3
color #fff
.action-button
display inline-block
font-size 1.2rem
color #fff
background-color $accentColor
padding 0.8rem 1.6rem
border-radius 4px
transition background-color 0.1s ease
box-sizing border-box
border-bottom 1px solid darken($accentColor, 10%)
&:hover
background-color lighten($accentColor, 10%)
.features
padding 2rem 0
margin-top 2.5rem
display flex
flex-wrap wrap
align-items flex-start
align-content stretch
justify-content space-between
.feature
flex-grow 1
flex-basis 30%
max-width 30%
text-align center
.image_title
width 11rem
height 11rem
animation heart 1.2s ease-in-out 0s infinite alternate
animation-play-state paused
h2
font-weight 500
font-size 1.3rem
color #fff
border-bottom none
padding-bottom 0
p
color #fff
opacity 0.8
.feature:hover
.image_title
animation-play-state: running
h2,p
opacity .7
// color var(--textLightenColor)
//
.slide-banner
margin-top: 2rem;
.banner-wrapper
position relative
.slide-banner-scroll
min-height 1px
overflow hidden
.slide-banner-wrapper
height 300px
.slide-item
display inline-block
height 300px
width 100%
text-align center
.image_title
width: 10rem;
height: 10rem;
h2
font-size: 1.1rem;
color: #fff;
font-weight: 500;
border-bottom: none;
padding-bottom: 0;
p
color: #b0b6be;
.docs-wrapper
position absolute
bottom 25px
left 50%
transform translateX(-50%)
.doc
display inline-block
margin 0 4px
width 8px
height 8px
border-radius 50%
background #2F455A
&.active
background #517EA9
.main-wrapper
margin 2rem auto
max-width $homePageWidth
position relative
display flex
flex-wrap wrap
align-items flex-start
align-content stretch
justify-content space-between
.feature
flex-grow 1
flex-basis 30%
max-width 30%
text-align center
.image_title
width 11rem
height 11rem
animation heart 1.2s ease-in-out 0s infinite alternate
animation-play-state paused
h2
font-weight 500
border-bottom none
padding-bottom 0
.feature:hover
.image_title
animation-play-state: running
h2,p
opacity .7
// color var(--textLightenColor)
.main-left
.card-box
padding 1rem 1.5rem
margin-bottom .9rem
.home-content
padding 1rem 1.5rem 0
flex 1
.main-right
.card-box
margin-left .9rem
.blogger-wrapper
padding 15px
height auto
display inline-table
.avatar
width 245px
height 245px
overflow hidden
img
width 100%
height 100%
border-radius 3px
.icons
border 1px solid var(--borderColor)
border-top none
height 40px
line-height 40px
a
font-size 20px
width 33%
color var(--textColor)
display block
float left
text-align center
opacity .8
&:hover
color $accentColor
.blogger
margin 15px 0 10px 0
.name
font-size 1.4rem
display: block
margin-bottom 6px
.slogan
color var(--textColor)
@keyframes heart
from{transform:translate(0,0)}
to{transform:translate(0,8px)}
@media (max-width: 1025px)
.i-body
background-color var(--bg)
body .home-content
.banner .banner-conent
.hero
h1
font-size 2.5rem
.description
font-size 1rem
.feature
h2
font-size 1.1rem
.image_title
width 10rem
height 10rem
.home-content
margin 0
border-radius 0
body .main-wrapper >*
.main-wrapper >*
box-shadow none
.banner .home
.hero h1
font-size 2.5rem
.feature h2
font-size 1.1rem
.hero .description
font-size 1rem
.home .feature .image_title
width 10rem
height 10rem
@media (max-width: 765px)
body .main-wrapper .info-wrapper
.main-wrapper .blogger-wrapper
width 200px
.avatar
width: 200px
height: 200px
@media (max-width: $MQMobile)
body .main-wrapper
.main-wrapper
margin 0
display block
.info-wrapper
.blogger-wrapper
display none
.home-content
padding-top 1.5rem
// 719px
.banner
// min-height 517px
.home .hero h1
// margin 1.8rem auto
.home
.features
display none
flex-direction column
margin-top 0
.feature
max-width 100%
padding 0 2.5rem
margin 0 auto
.banner-conent
.features
display none
flex-direction column
margin-top 0
.feature
max-width 100%
padding 0 2.5rem
margin 0 auto
@media (max-width: $MQMobileNarrow)
// 419px
.home
.banner-conent
padding-left 1.5rem
padding-right 1.5rem
.hero
img
max-height 210px
@ -457,12 +472,14 @@ body .main-wrapper
font-size: 2rem
h1, .description, .action
margin: 1.2rem auto
.description
font-size: 1.2rem
.action-button
font-size 1rem
padding 0.6rem 1.2rem
.feature
h2
font-size: 1.25rem
</style>
</style>

View File

@ -1,485 +0,0 @@
<template>
<div class="i-body" :style="footerBgImg && `background-image: url(${footerBgImg})`">
<!-- banner块 s -->
<div class="banner" :style="homeData.bgImg && `background: url(${$withBase(homeData.bgImg)}) center center / cover no-repeat`">
<div class="banner-conent" :style="!homeData.features && `padding-top: 7rem`">
<header class="hero">
<img v-if="homeData.heroImage" :src="$withBase(homeData.heroImage)" :alt="homeData.heroAlt || 'hero'" />
<h1 v-if="homeData.heroText !== null" id="main-title">{{ homeData.heroText || $title || 'Hello' }}</h1>
<p class="description">{{ homeData.tagline || $description || 'Welcome to your VuePress site' }}</p>
<p class="action" v-if="homeData.actionText && homeData.actionLink">
<NavLink class="action-button" :item="actionLink" />
</p>
</header>
<!-- PC端features块 s -->
<div class="features" v-if="homeData.features && homeData.features.length && !isMQMobile">
<div class="feature" v-for="(feature, index) in homeData.features" :key="index">
<router-link :to="feature.link">
<img class="image_title" :src="$withBase(feature.imgUrl)" :alt="feature.title" />
<h2>{{ feature.title }}</h2>
<p>{{ feature.details }}</p>
</router-link>
</div>
</div>
<!-- PC端features块 e -->
</div>
<!-- 移动端features块 s -->
<div class="slide-banner" v-if="homeData.features && homeData.features.length" v-show="isMQMobile">
<div class="banner-wrapper">
<div class="slide-banner-scroll" ref="slide">
<div class="slide-banner-wrapper">
<div class="slide-item" v-for="(feature, index) in homeData.features" :key="index">
<router-link :to="feature.link">
<img class="image_title" :src="$withBase(feature.imgUrl)" :alt="feature.title" />
<h2>{{ feature.title }}</h2>
<p>{{ feature.details }}</p>
</router-link>
</div>
</div>
</div>
<div class="docs-wrapper">
<span
class="doc"
v-for="(item, index) in homeData.features.length"
:key="index"
:class="{'active': currentPageIndex === index}"></span>
</div>
</div>
</div>
<!-- 移动端features块 e -->
</div>
<!-- banner块 e -->
<div class="main-wrapper">
<div class="main-left">
<PostList/>
<Content class="theme-vdoing-content custom card-box" />
<!-- <main class="home home-content" aria-labelledby="main-title">
<UpdateArticle
pageMark="home"
:length="updateBarConfig && updateBarConfig.onHome && updateBarConfig.onHome.length || 5"
:moreArticle="updateBarConfig && updateBarConfig.moreArticle"
v-if="isShowUpdateBar"
/>
</main> -->
</div>
<div class="main-right">
<aside class="blogger-wrapper card-box" v-if="blogger">
<div class="avatar">
<img :src="blogger.avatar" alt="头像" title="我好看吗">
</div>
<div class="icons" v-if="blogger.social">
<a
:href="item.link"
:title="item.title"
:class="['iconfont', item.iconClass]"
v-for="(item, index) in blogger.social.icons"
:key="index"
:style="{width: 100/blogger.social.icons.length + '%'}"
target="_blank"
>
</a>
</div>
<div class="blogger">
<span class="name">{{blogger.name}}</span>
<span class="slogan">
{{blogger.slogan}}
</span>
</div>
</aside>
</div>
</div>
<Footer />
</div>
</template>
<script>
import NavLink from "@theme/components/NavLink";
import BScroll from "@better-scroll/core"
import Slide from "@better-scroll/slide"
import UpdateArticle from './UpdateArticle'
import PostList from './PostList'
import Footer from './Footer'
const MOBILE_DESKTOP_BREAKPOINT = 720 // refer to config.styl
BScroll.use(Slide)
export default {
data(){
return {
isMQMobile: false,
slide: null,
currentPageIndex: 0,
playTimer: 0,
mark: 0,
updateBarConfig: null
}
},
created() {
this.updateBarConfig = this.$themeConfig.updateBar
},
beforeMount(){
this.isMQMobile = window.innerWidth < MOBILE_DESKTOP_BREAKPOINT ? true : false; // vupressbeforeCreate(),created()访apiwindow
window.addEventListener('resize', () => {
this.isMQMobile = window.innerWidth < MOBILE_DESKTOP_BREAKPOINT ? true : false;
if(this.isMQMobile && !this.slide && !this.mark){
this.mark++
setTimeout(() => {
this.init()
},60)
}
})
//
if(this.blogger && this.blogger.social && this.blogger.social.iconfontCssFile ) {
let linkElm = document.createElement("link")
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute("type", "text/css")
linkElm.setAttribute("href", this.blogger.social.iconfontCssFile)
document.head.appendChild(linkElm)
}
},
mounted() {
this.isMQMobile && this.init()
},
beforeDestroy() {
clearTimeout(this.playTimer)
this.slide && this.slide.destroy()
},
methods: {
init() {
clearTimeout(this.playTimer)
this.slide = new BScroll(this.$refs.slide, {
scrollX: true, // x
scrollY: false, // y
slide: {
loop: true,
threshold: 100
},
useTransition: true, // 使css3 transition
momentum: false,
bounce: false, //
stopPropagation: false, //
probeType: 2,
preventDefault: false
})
// user touches the slide area
this.slide.on('beforeScrollStart', () => {
clearTimeout(this.playTimer)
})
// user touched the slide done
this.slide.on('scrollEnd', () => {
this.autoGoNext()
})
this.slide.on('slideWillChange', (page) => {
this.currentPageIndex = page.pageX
})
this.autoGoNext()
},
autoGoNext() {
clearTimeout(this.playTimer)
this.playTimer = setTimeout(() => {
this.slide.next()
}, 4000)
}
},
components: { NavLink, UpdateArticle, PostList, Footer },
computed: {
homeData() {
return {
...this.$page.frontmatter,
base: this.$site.base
}
},
isShowUpdateBar() {
return this.updateBarConfig && this.updateBarConfig.onHome && this.updateBarConfig.onHome.isShow === false ? false : true
},
blogger() {
return this.$themeConfig.blogger
},
footerBgImg() {
return this.$themeConfig.footer && this.$themeConfig.footer.footerBgImg
},
actionLink() {
return {
link: this.homeData.actionLink,
text: this.homeData.actionText
};
}
}
};
</script>
<style lang="stylus">
.i-body
background bottom no-repeat
background-color rgba(220,220,220,0.1)
overflow hidden
.banner
width 100%
min-height 450px
margin-top $navbarHeight
background rgb(40,40,45)
color #fff
position relative
overflow hidden
background-image url(../images/bg-line.png)
background-size 35px 35px
.banner-conent
max-width $homePageWidth
margin 0px auto
position relative
z-index 1
overflow hidden
.hero
text-align center
margin-top 3rem
img
max-width 100%
max-height 192px
display block
margin 2rem auto 1.5rem
h1
margin 0
font-size 3.5rem
.description, .action
margin 1.5rem auto
.description
max-width 40rem
font-size 1.2rem
line-height 1.3
color #fff
.action-button
display inline-block
font-size 1.2rem
color #fff
background-color $accentColor
padding 0.8rem 1.6rem
border-radius 4px
transition background-color 0.1s ease
box-sizing border-box
border-bottom 1px solid darken($accentColor, 10%)
&:hover
background-color lighten($accentColor, 10%)
.features
padding 2rem 0
margin-top 2.5rem
display flex
flex-wrap wrap
align-items flex-start
align-content stretch
justify-content space-between
.feature
flex-grow 1
flex-basis 30%
max-width 30%
text-align center
.image_title
width 11rem
height 11rem
animation heart 1.2s ease-in-out 0s infinite alternate
animation-play-state paused
h2
font-weight 500
font-size 1.3rem
color #fff
border-bottom none
padding-bottom 0
p
color #fff
opacity 0.8
.feature:hover
.image_title
animation-play-state: running
h2,p
opacity .7
// color var(--textLightenColor)
//
.slide-banner
margin-top: 2rem;
.banner-wrapper
position relative
.slide-banner-scroll
min-height 1px
overflow hidden
.slide-banner-wrapper
height 300px
.slide-item
display inline-block
height 300px
width 100%
text-align center
.image_title
width: 10rem;
height: 10rem;
h2
font-size: 1.1rem;
color: #fff;
font-weight: 500;
border-bottom: none;
padding-bottom: 0;
p
color: #b0b6be;
.docs-wrapper
position absolute
bottom 25px
left 50%
transform translateX(-50%)
.doc
display inline-block
margin 0 4px
width 8px
height 8px
border-radius 50%
background #2F455A
&.active
background #517EA9
.main-wrapper
margin 2rem auto
max-width $homePageWidth
position relative
display flex
.main-left
.card-box
padding 1rem 1.5rem
margin-bottom .9rem
.home-content
padding 1rem 1.5rem 0
flex 1
.main-right
.card-box
margin-left .9rem
.blogger-wrapper
padding 15px
height auto
display inline-table
.avatar
width 245px
height 245px
overflow hidden
img
width 100%
height 100%
border-radius 3px
.icons
border 1px solid var(--borderColor)
border-top none
height 40px
line-height 40px
a
font-size 20px
width 33%
color var(--textColor)
display block
float left
text-align center
opacity .8
&:hover
color $accentColor
.blogger
margin 15px 0 10px 0
.name
font-size 1.4rem
display: block
margin-bottom 6px
.slogan
color var(--textColor)
@keyframes heart
from{transform:translate(0,0)}
to{transform:translate(0,8px)}
@media (max-width: 1025px)
.i-body
background-color var(--bg)
.banner .banner-conent
.hero
h1
font-size 2.5rem
.description
font-size 1rem
.feature
h2
font-size 1.1rem
.image_title
width 10rem
height 10rem
.home-content
margin 0
border-radius 0
.main-wrapper >*
box-shadow none
@media (max-width: 765px)
.main-wrapper .blogger-wrapper
width 200px
.avatar
width: 200px
height: 200px
@media (max-width: $MQMobile)
.main-wrapper
margin 0
display block
.blogger-wrapper
display none
.home-content
padding-top 1.5rem
// 719px
.banner
.banner-conent
.features
display none
flex-direction column
margin-top 0
.feature
max-width 100%
padding 0 2.5rem
margin 0 auto
@media (max-width: $MQMobileNarrow)
// 419px
.banner-conent
padding-left 1.5rem
padding-right 1.5rem
.hero
img
max-height 210px
margin 2rem auto 1.2rem
h1
font-size: 2rem
h1, .description, .action
margin: 1.2rem auto
.description
font-size: 1.2rem
.action-button
font-size 1rem
padding 0.6rem 1.2rem
.feature
h2
font-size: 1.25rem
</style>

View File

@ -0,0 +1,468 @@
<template>
<div class="i-body" :style="footerBgImg && `background-image: url(${footerBgImg})`">
<div class="banner" :style="data.bgImg && `background: url(${$withBase(data.bgImg)}) center center / cover no-repeat`">
<main class="home" :style="!data.features && `padding-top: 7rem`">
<header class="hero">
<img v-if="data.heroImage" :src="$withBase(data.heroImage)" :alt="data.heroAlt || 'hero'" />
<h1 v-if="data.heroText !== null" id="main-title">{{ data.heroText || $title || 'Hello' }}</h1>
<p class="description">{{ data.tagline || $description || 'Welcome to your VuePress site' }}</p>
<p class="action" v-if="data.actionText && data.actionLink">
<NavLink class="action-button" :item="actionLink" />
</p>
</header>
<!-- PC端features块 s -->
<div class="features" v-if="data.features && data.features.length && !isMQMobile">
<div class="feature" v-for="(feature, index) in data.features" :key="index">
<router-link :to="feature.link">
<img class="image_title" :src="$withBase(feature.imgUrl)" :alt="feature.title" />
<h2>{{ feature.title }}</h2>
<p>{{ feature.details }}</p>
</router-link>
</div>
</div>
<!-- PC端features块 e -->
</main>
<!-- 移动端slide s -->
<div class="slide-banner" v-if="data.features && data.features.length" v-show="isMQMobile">
<div class="banner-wrapper">
<div class="slide-banner-scroll" ref="slide">
<div class="slide-banner-wrapper">
<div class="slide-item" v-for="(feature, index) in data.features" :key="index">
<router-link :to="feature.link">
<img class="image_title" :src="$withBase(feature.imgUrl)" :alt="feature.title" />
<h2>{{ feature.title }}</h2>
<p>{{ feature.details }}</p>
</router-link>
</div>
</div>
</div>
<div class="docs-wrapper">
<span
class="doc"
v-for="(item, index) in data.features.length"
:key="index"
:class="{'active': currentPageIndex === index}"></span>
</div>
</div>
</div>
<!-- 移动端slide e -->
</div>
<div class="main-wrapper">
<main class="home home-content" aria-labelledby="main-title">
<UpdateArticle
pageMark="home"
:length="updateBarConfig && updateBarConfig.onHome && updateBarConfig.onHome.length || 5"
:moreArticle="updateBarConfig && updateBarConfig.moreArticle"
v-if="isShowUpdateBar"
/>
<Content class="theme-vdoing-content custom" />
</main>
<aside class="info-wrapper" v-if="blogger">
<div class="avatar">
<img :src="blogger.avatar" alt="头像">
</div>
<div class="icons" v-if="blogger.social">
<a
:href="item.link"
:title="item.title"
:class="['iconfont', item.iconClass]"
v-for="(item, index) in blogger.social.icons"
:key="index"
:style="{width: 100/blogger.social.icons.length + '%'}"
target="_blank"
>
</a>
</div>
<div class="blogger">
<span class="name">{{blogger.name}}</span>
<span class="slogan">
{{blogger.slogan}}
</span>
</div>
</aside>
</div>
<Footer />
</div>
</template>
<script>
import NavLink from "@theme/components/NavLink.vue";
import BScroll from "@better-scroll/core"
import Slide from "@better-scroll/slide"
import UpdateArticle from './UpdateArticle.vue'
import Footer from './Footer.vue'
const MOBILE_DESKTOP_BREAKPOINT = 720 // refer to config.styl
BScroll.use(Slide)
export default {
data(){
return {
isMQMobile: false,
slide: null,
currentPageIndex: 0,
playTimer: 0,
mark: 0,
updateBarConfig: null
}
},
created() {
this.updateBarConfig = this.$themeConfig.updateBar
},
beforeMount(){
this.isMQMobile = window.innerWidth < MOBILE_DESKTOP_BREAKPOINT ? true : false; // vupressbeforeCreate(),created()访apiwindow
window.addEventListener('resize', () => {
this.isMQMobile = window.innerWidth < MOBILE_DESKTOP_BREAKPOINT ? true : false;
if(this.isMQMobile && !this.slide && !this.mark){
this.mark++
setTimeout(() => {
this.init()
},60)
}
})
//
if(this.blogger && this.blogger.social && this.blogger.social.iconfontCssFile ) {
let linkElm = document.createElement("link")
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute("type", "text/css")
linkElm.setAttribute("href", this.blogger.social.iconfontCssFile)
document.head.appendChild(linkElm)
}
},
mounted() {
this.isMQMobile && this.init()
},
beforeDestroy() {
clearTimeout(this.playTimer)
this.slide && this.slide.destroy()
},
methods: {
init() {
clearTimeout(this.playTimer)
this.slide = new BScroll(this.$refs.slide, {
scrollX: true, // x
scrollY: false, // y
slide: {
loop: true,
threshold: 100
},
useTransition: true, // 使css3 transition
momentum: false,
bounce: false, //
stopPropagation: false, //
probeType: 2,
preventDefault: false
})
// user touches the slide area
this.slide.on('beforeScrollStart', () => {
clearTimeout(this.playTimer)
})
// user touched the slide done
this.slide.on('scrollEnd', () => {
this.autoGoNext()
})
this.slide.on('slideWillChange', (page) => {
this.currentPageIndex = page.pageX
})
this.autoGoNext()
},
autoGoNext() {
clearTimeout(this.playTimer)
this.playTimer = setTimeout(() => {
this.slide.next()
}, 4000)
}
},
components: { NavLink, UpdateArticle, Footer },
computed: {
data() {
return this.$page.frontmatter;
},
isShowUpdateBar() {
return this.updateBarConfig && this.updateBarConfig.onHome && this.updateBarConfig.onHome.isShow === false ? false : true
},
blogger() {
return this.$themeConfig.blogger
},
footerBgImg() {
return this.$themeConfig.footer && this.$themeConfig.footer.footerBgImg
},
actionLink() {
return {
link: this.data.actionLink,
text: this.data.actionText
};
}
}
};
</script>
<style lang="stylus">
//
.slide-banner
margin-top: 2rem;
.banner-wrapper
position relative
.slide-banner-scroll
min-height 1px
overflow hidden
.slide-banner-wrapper
height 300px
.slide-item
display inline-block
height 300px
width 100%
text-align center
.image_title
width: 10rem;
height: 10rem;
h2
font-size: 1.1rem;
color: #fff;
font-weight: 500;
border-bottom: none;
padding-bottom: 0;
p
color: #b0b6be;
.docs-wrapper
position absolute
bottom 25px
left 50%
transform translateX(-50%)
.doc
display inline-block
margin 0 4px
width 8px
height 8px
border-radius 50%
background #2F455A
&.active
background #517EA9
.i-body
background bottom no-repeat
// background-color var(--homeBg)
background-color rgba(220,220,220,0.1)
overflow hidden
.banner
width 100%
min-height 450px
background rgb(40,40,45)
color #fff
position relative
overflow hidden
background-image url(../images/bg-line.png)
background-size 35px 35px
.home
background none
position relative
z-index 1
.hero
h1
font-size 3.5rem
margin: 3.5rem auto 1.8rem auto
.description
font-size 1.2rem
color #fff
.features
border-top none
.feature
h2
font-size 1.3rem
color #fff
p
color #fff
opacity 0.8
// color #B0B6BE
body .main-wrapper
margin 2rem auto
max-width 1080px
position relative
display flex
>*
border-radius 5px
background var(--bg)
box-shadow 0 1px 2px 0 rgba(0,0,30,.1), 0 2px 4px 0 rgba(0,0,0,.1)
.home-content
padding 1rem 1.5rem 0
flex 1
.info-wrapper
width 260px
padding 15px
height auto
margin-left 10px
display inline-table
.avatar
width 260px
height 260px
overflow hidden
img
width 100%
height 100%
border-radius 3px
.icons
border 1px solid var(--borderColor)
height 40px
line-height 40px
a
font-size 20px
width 33%
color var(--textColor)
display block
float left
text-align center
opacity .8
&:hover
color $accentColor
.blogger
margin 15px 0 10px 0
.name
font-size 24px
display: block
margin-bottom 10px
.slogan
color var(--textColor)
.home
padding $navbarHeight 2rem 0
max-width 1080px
margin 0px auto
display block
.hero
text-align center
img
max-width 100%
max-height 192px
display block
margin 2rem auto 1.5rem
h1
font-size 3rem
h1, .description, .action
margin 1.8rem auto
.description
max-width 40rem
font-size 1.4rem
line-height 1.3
color var(--textLightenColor)
.action-button
display inline-block
font-size 1.2rem
color #fff
background-color $accentColor
padding 0.8rem 1.6rem
border-radius 4px
transition background-color 0.1s ease
box-sizing border-box
border-bottom 1px solid darken($accentColor, 10%)
&:hover
background-color lighten($accentColor, 10%)
.features
border-top 1px solid var(--borderColor)
padding 2rem 0
margin-top 2.5rem
display flex
flex-wrap wrap
align-items flex-start
align-content stretch
justify-content space-between
.feature
flex-grow 1
flex-basis 30%
max-width 30%
text-align center
.image_title
width 11rem
height 11rem
animation heart 1.2s ease-in-out 0s infinite alternate
animation-play-state paused
h2
font-weight 500
border-bottom none
padding-bottom 0
.feature:hover
.image_title
animation-play-state: running
h2,p
opacity .7
// color var(--textLightenColor)
@keyframes heart
from{transform:translate(0,0)}
to{transform:translate(0,8px)}
@media (max-width: 1025px)
.i-body
background-color var(--bg)
body .home-content
margin 0
border-radius 0
body .main-wrapper >*
box-shadow none
.banner .home
.hero h1
font-size 2.5rem
.feature h2
font-size 1.1rem
.hero .description
font-size 1rem
.home .feature .image_title
width 10rem
height 10rem
@media (max-width: 765px)
body .main-wrapper .info-wrapper
width 200px
.avatar
width: 200px
height: 200px
@media (max-width: $MQMobile)
body .main-wrapper
margin 0
display block
.info-wrapper
display none
.home-content
padding-top 1.5rem
// 719px
.banner
// min-height 517px
.home .hero h1
// margin 1.8rem auto
.home
.features
display none
flex-direction column
margin-top 0
.feature
max-width 100%
padding 0 2.5rem
margin 0 auto
@media (max-width: $MQMobileNarrow)
// 419px
.home
padding-left 1.5rem
padding-right 1.5rem
.hero
img
max-height 210px
margin 2rem auto 1.2rem
h1
font-size: 2rem
h1, .description, .action
margin: 1.2rem auto
.description
font-size: 1.2rem
.action-button
font-size 1rem
padding 0.6rem 1.2rem
.feature
h2
font-size: 1.25rem
</style>

View File

@ -54,9 +54,6 @@ export default {
},
mounted() {
const fmData = this.$frontmatter.pageComponent.data
if(fmData && fmData.tagBgColor) {
this.pageData.tagBgColor = fmData.tagBgColor
}
if(fmData && fmData.slogan) {
this.pageData.slogan = fmData.slogan
}

View File

@ -1,14 +0,0 @@
#批量添加和修改front matter配置文件
# 防止误操作每次批量修改时手动改成true修改完成后会自动变成false
editable: true
# 需要批量处理的路径docs文件夹内的文件夹
path:
- 01.前端
- 25.JavaScript文章
# 要写入front matter的数据
data:
tags:
- js

12
utils/config.yml Normal file
View File

@ -0,0 +1,12 @@
#批量添加和修改、删除front matter配置文件
# 需要批量处理的路径docs文件夹内的文件夹
path:
- 《ES6 教程》笔记
# delete: true # 是否删除字段操作
# 要写入或删除front matter的数据 front matter中没有的数据则添加已有的数据则覆盖。如果是删除操作会忽略字段的值。
data:
author:
name: 阮一峰

View File

@ -1,126 +1,62 @@
/**
* 批量添加和修改front matter
* 批量添加和修改front matter 需要 ./config.yml 配置文件的配合
*/
const fs = require('fs'); // 文件模块
const path = require('path'); // 路径模块
const logger = require('tracer').colorConsole(); // 控制台工具(用于控制台打印信息包含时间、打印类型、文件及代码行号、对象、颜色)
const matter = require('gray-matter'); // FrontMatter解析器 https://github.com/jonschlinkert/gray-matter
const jsonToYaml = require('json2yaml')
const yamlToJs = require('yamljs')
const arg = process.argv.splice(2)[0]; // 获取命令行传入的参数
const inquirer = require('inquirer') // 命令行操作
const readFileList = require('./modules/readFileList');
const { type, repairDate} = require('./modules/fn');
const configFile = require('./config.yaml')
const configPath = path.join(__dirname, 'config.yml') // 配置文件的路径
// const configStr = fs.readFileSync(, 'utf8');
console.log(fs.readFileSync(configFile).toString())
// const configDate = yamlToJs.parse(fs.readFileSync(configFile).toString())
// const fm = {
// data: {
// tags: ['js']
// },
// path: ['01.前端','25.JavaScript文章22']
// }
// console.log(config)
// const filePath = path.join(__dirname, '..', 'docs', ...config.path);
// main();
main();
/**
* 主体函数
*/
function main() {
async function main() {
const promptList = [{
type: "confirm",
message: "批量操作frontmatter有修改数据的风险确定要继续吗",
name: "edit",
}];
let edit = true;
await inquirer.prompt(promptList).then(answers => {
edit = answers.edit
})
if(!edit) { // 退出操作
return
}
const config = yamlToJs.load(configPath) // 解析配置文件的数据转为js对象
const filePath = path.join(__dirname, '..', 'docs', ...config.path); // 要批量修改的文件路径
const files = readFileList(filePath); // 读取所有md文件数据
console.log(files)
files.forEach(file => {
let dataStr = fs.readFileSync(file.filePath, 'utf8');// 读取每个md文件的内容
const fileMatterObj = matter(dataStr) // 解析md文件的front Matter。 fileMatterObj => {content:'剔除frontmatter后的文件内容字符串', data:{<frontmatter对象>}, ...}
let matterData = fileMatterObj.data; // 得到md文件的front Matter
// files.forEach(file => {
// let dataStr = fs.readFileSync(file.filePath, 'utf8');// 读取每个md文件内容
// /**
// * fileMatterObj => {content:'剔除frontmatter后的文件内容字符串', data:{<frontmatter对象>}, ...}
// */
// const fileMatterObj = matter(dataStr);
// if (Object.keys(fileMatterObj.data).length === 0) { // 未定义FrontMatter数据
// const stat = fs.statSync(file.filePath);
// const dateStr = dateFormat(stat.birthtime);// 文件的创建时间
// const newData = `---\r\ntitle: ${file.name}\r\ndate: ${dateStr}\r\npermalink: ${file.permalink}\r\n---\r\n` + fileMatterObj.content;
// fs.writeFileSync(file.filePath, newData); // 写入
// console.log(`write FrontMatter${file.filePath} `)
// } else { // 已有FrontMatter
// const matterData = fileMatterObj.data;
// let mark = false;
// // 已有FrontMatter但是没有title、date、permalink数据的
// if (!matterData.hasOwnProperty('title')) {
// matterData.title = file.name;
// mark = true;
// }
// if (!matterData.hasOwnProperty('date')) {
// const stat = fs.statSync(file.filePath);
// matterData.date = dateFormat(stat.birthtime);
// mark = true;
// }
// if (!matterData.hasOwnProperty('permalink')) {
// matterData.permalink = file.permalink;
// mark = true;
// }
// if (mark) {
// if(matterData.date && type(matterData.date) === 'date') {
// matterData.date = repairDate(matterData.date) // 修复时间格式
// }
// const newData = jsonToYaml.stringify(matterData).replace(/\n\s{2}/g,"\n") + '---\r\n' + fileMatterObj.content;
// fs.writeFileSync(file.filePath, newData); // 写入
// console.log(`update FrontMatter${file.filePath} `)
// }
// // 更新title和permalink
// if (arg === '-update' && matterData.title != file.name){ // 当title和文件名不一致时才更新
// matterData.title = file.name;
// if (/pages/.test(matterData.permalink)) {
// matterData.permalink = file.permalink;
// }
// // 修复date时区和格式被修改的问题 (并非更新date的值)
// matterData.date = repairDate(matterData.date);
// const newData2 = jsonToYaml.stringify(JSON.parse(JSON.stringify(matterData))) + '---\r\n' + fileMatterObj.content;
// fs.writeFileSync(file.filePath, newData2); // 写入
// console.log(`update FrontMatter title and permalink${file.filePath}`)
// }
// }
if (config.delete == true) { // 删除操作
for(let key in config.data) {
delete matterData[key]
}
} else { // 添加、修改操作
Object.assign(matterData, config.data) // 将配置数据合并到front Matter对象
}
// })
}
// 类型判断
function type(o){
var s = Object.prototype.toString.call(o)
return s.match(/\[object (.*?)\]/)[1].toLowerCase()
}
// 修复date时区格式的问题
function repairDate(date) {
date = new Date(date);
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth()+1)}-${zero(date.getUTCDate())} ${zero(date.getUTCHours())}:${zero(date.getUTCMinutes())}:${zero(date.getUTCSeconds())}`;
}
// 日期的格式
function dateFormat(date) {
return `${date.getFullYear()}-${zero(date.getMonth()+1)}-${zero(date.getDate())} ${zero(date.getHours())}:${zero(date.getMinutes())}:${zero(date.getSeconds())}`
}
// 小于10补0
function zero(d){
return d.toString().padStart(2,'0')
if(matterData.date && type(matterData.date) === 'date') {
matterData.date = repairDate(matterData.date) // 修复时间格式
}
const newData = jsonToYaml.stringify(matterData).replace(/\n\s{2}/g,"\n").replace(/"/g,"") + '---\r\n' + fileMatterObj.content;
fs.writeFileSync(file.filePath, newData); // 写入
console.log(`update frontmatter${file.filePath} `)
})
}

View File

@ -7,6 +7,7 @@ const matter = require('gray-matter'); // FrontMatter解析器 https://github.co
const jsonToYaml = require('json2yaml')
const arg = process.argv.splice(2)[0]; // 获取命令行传入的参数
const readFileList = require('./modules/readFileList');
const { type, repairDate, dateFormat} = require('./modules/fn');
main();
@ -29,7 +30,7 @@ function main() {
const dateStr = dateFormat(stat.birthtime);// 文件的创建时间
const newData = `---\r\ntitle: ${file.name}\r\ndate: ${dateStr}\r\npermalink: ${file.permalink}\r\n---\r\n` + fileMatterObj.content;
fs.writeFileSync(file.filePath, newData); // 写入
console.log(`write FrontMatter${file.filePath} `)
console.log(`write frontmatter${file.filePath} `)
} else { // 已有FrontMatter
const matterData = fileMatterObj.data;
@ -56,9 +57,9 @@ function main() {
if(matterData.date && type(matterData.date) === 'date') {
matterData.date = repairDate(matterData.date) // 修复时间格式
}
const newData = jsonToYaml.stringify(matterData).replace(/\n\s{2}/g,"\n") + '---\r\n' + fileMatterObj.content;
const newData = jsonToYaml.stringify(matterData).replace(/\n\s{2}/g,"\n").replace(/"/g,"") + '---\r\n' + fileMatterObj.content;
fs.writeFileSync(file.filePath, newData); // 写入
console.log(`update FrontMatter${file.filePath} `)
console.log(`update frontmatter${file.filePath} `)
}
@ -71,7 +72,7 @@ function main() {
// 修复date时区和格式被修改的问题 (并非更新date的值)
matterData.date = repairDate(matterData.date);
const newData2 = jsonToYaml.stringify(JSON.parse(JSON.stringify(matterData))).replace(/\n\s{2}/g,"\n") + '---\r\n' + fileMatterObj.content;
const newData2 = jsonToYaml.stringify(JSON.parse(JSON.stringify(matterData))).replace(/\n\s{2}/g,"\n").replace(/"/g,"") + '---\r\n' + fileMatterObj.content;
fs.writeFileSync(file.filePath, newData2); // 写入
console.log(`update FrontMatter title and permalink${file.filePath}`)
}
@ -82,24 +83,4 @@ function main() {
}
// 类型判断
function type(o){
var s = Object.prototype.toString.call(o)
return s.match(/\[object (.*?)\]/)[1].toLowerCase()
}
// 修复date时区格式的问题
function repairDate(date) {
date = new Date(date);
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth()+1)}-${zero(date.getUTCDate())} ${zero(date.getUTCHours())}:${zero(date.getUTCMinutes())}:${zero(date.getUTCSeconds())}`;
}
// 日期的格式
function dateFormat(date) {
return `${date.getFullYear()}-${zero(date.getMonth()+1)}-${zero(date.getDate())} ${zero(date.getHours())}:${zero(date.getMinutes())}:${zero(date.getSeconds())}`
}
// 小于10补0
function zero(d){
return d.toString().padStart(2,'0')
}

21
utils/modules/fn.js Normal file
View File

@ -0,0 +1,21 @@
// 类型判断
exports.type = function (o){
var s = Object.prototype.toString.call(o)
return s.match(/\[object (.*?)\]/)[1].toLowerCase()
}
// 修复date时区格式的问题
exports.repairDate = function (date) {
date = new Date(date);
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth()+1)}-${zero(date.getUTCDate())} ${zero(date.getUTCHours())}:${zero(date.getUTCMinutes())}:${zero(date.getUTCSeconds())}`;
}
// 日期的格式
exports.dateFormat = function (date) {
return `${date.getFullYear()}-${zero(date.getMonth()+1)}-${zero(date.getDate())} ${zero(date.getHours())}:${zero(date.getMinutes())}:${zero(date.getSeconds())}`
}
// 小于10补0
function zero(d){
return d.toString().padStart(2,'0')
}