一念

一念 查看完整档案

广州编辑  |  填写毕业院校  |  填写所在公司/组织 segmentfault.com/u/lightrrrr 编辑
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

一念 发布了文章 · 2019-09-18

Spring Boot Actuator的常用端点

Actuator 预定义的端点

/auditevents -列出与安全审计相关的事件,例如用户登录/注销。此外,我们可以按主要或类型等字段进行过滤
/beans -在我们的BeanFactory中使用所有可用的bean
/conditions -以前称为/ autoconfig,构建有关自动配置的条件报告
/configprops -允许我们获取所有@ConfigurationProperties的bean
/env -返回当前环境属性。此外,我们可以检索单个属性
/flyway -提供有关我们的Flyway数据库迁移的详细信息
/health -提供有关应用程序的运行状况的详细信息
/heapdump -从应用程序的JVM提供了一个堆转储
/info -提供有关应用程序的一般信息
/liquibase -提供有关Liquibase应用数据库的变更集信息
/logfile -可以访问应用程序的日志文件的内容
/loggers -可以访问和修改应用程序的记录程序及其级别的配置。
/metrics -详细说明我们的应用程序的指标。这可能包括通用指标和自定义指标
/prometheus -返回与metrics相同的指标,但格式化为与Prometheus服务器一起使用
/scheduledtasks -提供有关应用程序的计划任务的信息
/sessions -列出我们正在使用Spring Session的HTTP会话的信息
/shutdown -用来关闭应用程序
/threaddump -查看底层JVM的线程信息

更多详情可以查看官方文档 Spring Boot Actuator Web API Documentation

查看原文

赞 0 收藏 0 评论 0

一念 发布了文章 · 2019-03-27

Docker 入门

安装 Docker For Windows

Docker For Windows 仅支持window 10(64位) 专业版、企业版、教育版或者更高版本

双击Docker Desktop for Windows Installer.exe以运行安装程序。如果您尚未下载安装程序(Docker Desktop Installer.exe),则可以从download.docker.com获取 。

安装后Docker不会自动启动。要启动它,请搜索Docker,在搜索结果中选择Docker Desktop for Windows,然后单击它(或按Enter键)。

clipboard.png

安装过程可能会多次自动重启,当桌面右下角的 Docker Desktop is starting 变成 Docker Desktop is running 时表示安装完成。

当状态栏中的鲸鱼保持稳定时,Docker正在运行,并且可以从任何终端窗口访问。

clipboard.png

如果鲸鱼隐藏在通知区域中,请单击任务栏上的向上箭头以显示它。

clipboard.png

参考:

查看原文

赞 0 收藏 0 评论 0

一念 发布了文章 · 2019-03-03

Spring Data JPA 教程系列

使用 JPA 访问数据

创建项目

打开IDEA -> Create New Project

clipboard.png

clipboard.png

clipboard.png

clipboard.png

创建目录

clipboard.png

创建实体

package com.example.demo.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Customer {

    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;

    protected Customer() {
    }

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", firstName=" + firstName +
                ", lastName=" + lastName +
                '}';
    }
}

创建 repository

创建与实体对应的Repository

package com.example.demo.repository;

import com.example.demo.entity.Customer;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface CustomerRepository extends CrudRepository<Customer, Long> {

    List<Customer> findByLastName(String lastName);

}

通过继承CrudRepository继承几种增删改查方法,也可以通过方法名支定义其他查询方法。

添加启动加载类 CommandLineRunner 测试

package com.example.demo;

import com.example.demo.entity.Customer;
import com.example.demo.repository.CustomerRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringDataJpaDemoApplication {

    public static final Logger log = LoggerFactory.getLogger(SpringDataJpaDemoApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(SpringDataJpaDemoApplication.class, args);
    }

    @Bean
    public CommandLineRunner demo(CustomerRepository repository) {
        return (args -> {

            repository.save(new Customer("Jack", "Bauer"));
            repository.save(new Customer("Chloe", "Brian"));
            repository.save(new Customer("Kim", "Bauer"));
            repository.save(new Customer("David", "Palmer"));
            repository.save(new Customer("Michelle", "Dessler"));

            log.info("Customer found with save() finish");

            log.info("Customer found with findAll()");
            log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            for (Customer customer : repository.findAll()) {
                log.info(customer.toString());
            }
            log.info("");

            repository.findById(1L).ifPresent(customer -> {
                log.info("Customer found with findById()");
                log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                log.info(customer.toString());
                log.info("");
            });

            log.info("Customer found with findByLastName('findByLastName')");
            log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            repository.findByLastName("Bauer").forEach(bauer -> {
                log.info(bauer.toString());
            });
            log.info("");

        });
    }


}

运行程序,通过 log 查看效果

使用 REST 访问 JPA 数据

pom.xml 添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <dependencies>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        
    </dependencies>


</project>

创建实体

package com.example.demo.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Person {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    
    private String firstName;
    private String lastName;
    
    
    public String getFirstName() {
        return firstName;
    }
    
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    
    public String getLastName() {
        return lastName;
    }
    
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

创建 repository

package com.example.demo.repository;

import com.example.demo.entity.Person;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

import java.util.List;

@RepositoryRestResource
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
    
    List<Person> findPersonByLastName(@Param("name") String name);
    
}

此repository是一个接口,允许您执行涉及Person对象的各种操作。它通过继承Spring Data Commons中定义的PagingAndSortingRepository接口来获取这些操作

在运行时,Spring Data REST将自动创建此接口的实现。然后它将使用@RepositoryRestResource注解指导Spring MVC创建RESTful端点/persons。

测试程序

首先看到顶层服务

curl http://localhost:8080/
{
  "_links" : {
    "customers" : {
      "href" : "http://localhost:8080/customers"
    },
    "persons" : {
      "href" : "http://localhost:8080/persons{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://localhost:8080/profile"
    }
  }
}
Spring Data REST使用HAL格式进行JSON输出。它非常灵活,可以方便地提供与所服务数据相邻的链接。
curl http://localhost:8080/persons
{
  "_embedded" : {
    "persons" : [ ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/persons"
    },
    "search" : {
      "href" : "http://localhost:8080/persons/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 0,
    "totalPages" : 0,
    "number" : 0
  }
}

可以看到customers的也跟着显示出来了,我们可以通过注释隐藏,当然也可以全局隐藏:

设置存储库检测策略

Spring Data REST使用RepositoryDetectionStrategy来确定是否将存储库导出为REST资源。的RepositoryDiscoveryStrategies列举包括以下值:

NameDescription
DEFAULT默认,ANNOTATION + VISIBILITY
ALL公开所有Repository
ANNOTATION公开@RepositoryRestResource和@RestResource注解的Repository,除非exported设置为false
VISIBILITY暴露所有public修饰的Repository

创建配置类

package com.example.demo.config;

import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.core.mapping.RepositoryDetectionStrategy;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
import org.springframework.stereotype.Component;

@Component
public class RestConfigurer implements RepositoryRestConfigurer {

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);
    }

}

测试

curl http://localhost:8080/
{
  "_links" : {
    "persons" : {
      "href" : "http://localhost:8080/persons{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://localhost:8080/profile"
    }
  }
}

分页和排序

分页

Pageable 是一个由 Spring 定义的接口,它拥有一个实现 PageRequest。让我们看看如何创建一个 PageRequest。

Pageable pageable = PageRequest.of(0, 10);
Page<Employee> page = repository.findAll(pageable);

// 也可以简单一点

Page<Employee> page = repository.findAll(PageRequest.of(0, 10));

表示请求第一页10个数据。

如果我们要访问下一页,我们可以每次增加页码。

PageRequest.of(1, 10);
PageRequest.of(2, 10);
PageRequest.of(3, 10);
...

排序

Spring Data JPA 提供一个Sort对象提供排序机制。让我们看一下排序的方式。

repository.findAll(Sort.by("fistName"));

repository.findAll(Sort.by("fistName").ascending().and(Sort.by("lastName").descending());

同时排序和分页

Pageable pageable = PageRequest.of(0, 20, Sort.by("firstName"));

Pageable pageable = PageRequest.of(0, 20, Sort.by("fistName").ascending().and(Sort.by("lastName").descending());

按示例对象查询

QueryByExampleExecutor

构建复杂查询

SpringData JPA 为了实现 "Domain Driven Design" 中的规范概念,提供了一些列的 Specification 接口,其中最常用的便是 :JpaSpecificationExecutor。

使用 SpringData JPA 构建复杂查询(join操作,聚集操作等等)都是依赖于 JpaSpecificationExecutor 构建的 Specification 。

查看原文

赞 1 收藏 1 评论 0

一念 关注了专栏 · 2019-02-26

SegmentFault 社区周刊

主题技术周刊,每周分享新鲜有趣的技术干货。

关注 1265

一念 发布了文章 · 2019-02-15

微服务所需组件(大部分是Spring Cloud,持续更新)

服务发现 | 服务治理 | 注册中心

将所有微服务注册到一个Server上,然后通过心跳进行服务健康监测。这样服务A调用服务B可以通过注册中心获取服务B的地址、端口调用

  • Eureka - Eureka 提供云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移
  • Spring Cloud Zookeeper - Spring Cloud Zookeeper 操作Zookeeper的工具包,用于使用zookeeper方式的服务发现和配置管理
  • Consul - Consul 是一个服务发现与配置工具,与Docker容器可以无缝集成

服务调用

HTTP 客户端

  • restTemplate - Spring Web RestTemplate 是同步客户端执行HTTP请求,在底层HTTP客户端库上公开简单的模板方法API,类使于JDK HttpURLConnection、Feign等
  • Feign - Feign 使Java编写HTTP客户端更加简单

restTemplate和Feign都可以配合Ribbon提供负载均衡

负载均衡

  • Ribbon - Ribbon 提供云端负载均衡,有多种负载均衡策略可供选择

熔断器

  • Hystrix - Hystrix 旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。

路由网关

  • Gateway - Spring Cloud Gateway 旨在提供一种简单而有效的方式来路由到API,并为他们提供横切关注点
  • Zuul - Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架

路由网关接受所有的请求,,有着很高的负载,因此它通常是一个集群。所有的请求都hui先经过一层负载均衡被发到路由网关

配置管理

  • Spring Cloud Config - Spring Cloud Config 配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git以及Subversion

事件、消息总线

  • Spring Cloud Bus - Spring Cloud Bus 事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署

问题定位 | 链路跟踪

  • Spring Cloud Sleuth - Spring Cloud Sleuth 日志收集工具包,封装了Dapper和log-based追踪以及Zipkin和HTrace操作,为SpringCloud应用实现了一种分布式追踪解决方案
查看原文

赞 0 收藏 0 评论 0

一念 发布了文章 · 2019-02-15

Java 开源库精选(持续更新)

仅记录亲自使用和考虑使用的

Apache Commons

  • Commons IO - Commons IO 是一个帮助开发IO功能的实用程序库
  • Commons Configuration - Commons Configuration 提供了一个通用配置界面,使Java应用程序可以从各种来源读取配置数据。
  • 查看更多可重用、稳定的 Commons 组件

Spring

Spring 公共类

  • Spring Web RestTemplate - RestTemplate 是同步客户端执行HTTP请求,在底层HTTP客户端库上公开简单的模板方法API,类使于JDK HttpURLConnection、Feign等
  • Spring Reactive WebClient - WebClient 是reactive版的RestTemplate

社区开源

  • Feign - Feign 使Java编写HTTP客户端更加简单
查看原文

赞 0 收藏 0 评论 0

一念 发布了文章 · 2019-02-13

VuePress 静态网站生成

使用技术:

  • VuePress - Vue 驱动的静态网站生成器
仓库地址:https://github.com/yinian-R/v...

全局安装

## 安装
yarn global add vuepress # 或者:npm install -g vuepress

现有项目

如果你想在一个现有项目中使用 VuePress,同时想要在该项目中管理文档,则应该将 VuePress 安装为本地依赖。

## 没有项目可以初始化
yarn init

## 将 VuePress 作为一个本地依赖安装
yarn add -D vuepress # 或者:npm install -D vuepress

## 新建一个 docs 文件夹
mkdir docs

## 新建一个 markdown 文件
echo # Hello VuePress! > docs/README.md

## 开始写作
npx vuepress dev docs

接着,在 package.json 里加一些脚本:

{
  "scripts": {
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs"
  }
}

基本配置

.
├─ docs
│  ├─ README.md
│  └─ .vuepress
│     └─ config.js

一个 VuePress 网站必要的配置文件是 .vuepress/config.js,它应该导出一个 JavaScript 对象:

module.exports = {
  title: 'Hello VuePress',
  description: 'Just playing around'
}

静态资源

创建public文件夹,主要用于存放静态资源

.
├─ docs
│  └─ .vuepress
│     └─ public
│          └─ image
│               └─ favicon.ico

添加网站 favicon,修改 .vuepress/config.js 内容

module.exports = {
    head:[
        ['link', {rel:'icon', href:'/image/favicon.ico'}]
    ]
};

导航栏

你可以通过 themeConfig.nav 增加一些导航栏链接:

module.exports = {
    themeConfig: {
        nav: [
            { text: '主页', link: '/' },
            { text: '指南', link: '/guide/' },
            {
                text: '语言',
                items: [
                    { text: '中文', link: '/language/chinese/' },
                    { text: 'English', link: '/language/english/' }
                ]
            },
            { text: 'GitHub', link: 'https://github.com' }
        ]
    }
};

首页

需要在dosc/README.md指定 home: true

---
home: true
heroImage: /image/favicon.ico
heroText: Hero 标题
tagline: Hero 副标题
actionText: 快速上手 →
actionLink: /guide/
features:
- title: 简洁至上
  details: 以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。
- title: Vue驱动
  details: 享受 Vue + webpack 的开发体验,在 Markdown 中使用 Vue 组件,同时可以使用 Vue 来开发自定义主题。
- title: 高性能
  details: VuePress 为每个页面预渲染生成静态的 HTML,同时在页面被加载的时候,将作为 SPA 运行。
footer: MIT Licensed | Copyright © 2018-present Evan You
---

侧边栏

想要使 侧边栏(Sidebar)生效,需要配置 themeConfig.sidebar,基本的配置,需要一个包含了多个链接的数组:

module.exports = {
    themeConfig: {
        sidebar: [
            '/',
            ['/hello', 'hello page']
        ]
    }
};

部署

设置部署站点的基础路径。

module.exports = {

    base: '/vuepress-demo/',
    
};

在你的项目中,创建一个如下的 deploy.sh 文件

#!/usr/bin/env bash
# 确保脚本抛出遇到的错误
set -e

# 生成静态文件
npm run docs:build

# 进入生成的文件夹
cd docs/.vuepress/dist

# 如果是发布到自定义域名
# echo 'www.example.com' > CNAME

git init
git add -A
git commit -m 'deploy'

# 如果发布到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master

# 如果发布到 https://<USERNAME>.github.io/<REPO>
 git push -f git@github.com:yinian-R/vuepress-demo.git master:gh-pages

cd -
查看原文

赞 1 收藏 1 评论 0

一念 赞了文章 · 2019-02-13

VuePress从零开始搭建自己专属博客

VuePress从零开始搭建自己的博客

最近将自己的博客从Hexo转移到VuePress中来,使用VuePress的过程中也遇到了一些问题,写一篇文章来记录一下搭建过程和踩过的坑。

VuePress是什么?

VuePress是以Vue驱动的静态网站生成器,是一个由Vue、Vue Router和webpack驱动的单页应用。在VuePress中,你可以使用Markdown编写文档,然后生成网页,每一个由VuePress生成的页面都带有预渲染好的HTML,也因此具有非常好的加载性能和搜索引擎优化。同时,一旦页面被加载,Vue将接管这些静态内容,并将其转换成一个完整的单页应用,其他的页面则会只在用户浏览到的时候才按需加载。

详情请看VuePress官方文档

VuePress特性

  • 为技术文档而优化的内置Markdown拓展
  • 在Markdown文件中使用Vue组件的能力
  • Vue驱动的自定义主题系统
  • 自动生成Service Worker(支持PWA)
  • Google Analytics集成
  • 基于Git的"最后更新时间"
  • 多语言支持
  • 响应式布局

环境搭建

安装

VuePress支持使用Yarn和npm来安装,Node.js版本需要>=8才可以。

全局安装VuePress

yarn global add vuepress # 或者:npm install -g vuepress

创建项目目录

mkdir project
cd project

初始化项目

yarn init -y # 或者 npm init -y

新建docs文件夹

docs文件夹作为项目文档根目录,主要放置Markdown类型的文章和.vuepress文件夹。

mkdir docs

设置package.json

VuePress中有两个命令,vuepress dev docs命令运行本地服务,通过访问http://localhost:8080即可预览网站,vuepress build docs命令用来生成静态文件,默认情况下,放置在docs/.vuepress/dist目录中,当然你也可以在docs/.vuepress/config.js中的dest字段来修改默认存放目录。在这里将两个命令封装成脚本的方式,直接使用npm run docs:dev和npm run docs:build即可。

{
  "scripts": {
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs"
  }
}

创建.vuepress目录

在docs目录中,创建.vuepress目录,.vuepress目录主要用于存放VuePress相关的文件。

mkdir .vuepress

创建config.js

进入到.vuepress目录中,然后创建config.js,config.js是VuePress必要的配置文件,它导出y一个javascript对象。

touch config.js

创建public文件夹

进入到.vuepress目录中,然后创建public文件夹,此文件夹主要放静态资源文件,例如favicons和 PWA的图标。

mkdir public

此时,项目的结构差不多就出来了。

project
├─── docs
│   ├── README.md
│   └── .vuepress
│       ├── public
│       └── config.js
└── package.json

以上只是简单了搭建了一下博客的开发环境,接下来是博客主要的基本配置config.js,也是必须要做的。

基本配置

一个config.js的主要配置包括网站的标题、描述等基本信息,以及主题的配置。这里简单的列举一下常用配置。

网站信息

module.exports = {
    title: '个人主页', 
    description: '姜帅杰的博客',
    head: [
        ['link', { rel: 'icon', href: '/img/logo.ico' }],
        ['link', { rel: 'manifest', href: '/manifest.json' }],
    ]
}
  • title:网站标题
  • description:网站描述
  • head:额外的需要被注入到当前页面的HTML"head"中的标签,其中路径的"/"就是public资源目录。

具体配置详情请看文档:配置

主题配置

module.exports = {
       themeConfig: {
        nav: [
            { text: '主页', link: '/' },
            { text: '博文',
              items: [
                { text: 'Android', link: '/android/' },
                { text: 'ios', link: '/ios/' },
                { text: 'Web', link: '/web/' }
              ] 
            },
            { text: '关于', link: '/about/' },
            { text: 'Github', link: 'https://www.github.com/codeteenager' },
        ],
        sidebar: {
            '/android/': [
                        "",
                        "android1", 
                         ...
                         ],
                "/ios/":[
                        "",
                        "ios1",
                        ],
                "/web/":[
                        "",
                        "web1",
                        ...
                             ],
            },
        sidebarDepth: 2,
        lastUpdated: 'Last Updated', 
    },
}
  • nav:导航栏配置,此配置主要用于配置导航栏的链接,例如以上主页的link为"/",默认是根目录下的README.md。"/android/"链接到根目录docs下的android文件夹下的README.md文件。
  • sidebar:侧边栏配置,你可以省略.md拓展名,同时以/结尾的路径将会被视为 */README.md。'/android/'、'/ios/'和'/web/'是通过路由的方式将每个页面的标题抽取出来显示。"/android/"是指根目录下android文件夹中的路由,每个路由链接都要有README.md。所以目录结构如下:

    ├─── docs
    ├── README.md
    └── android
    │   └── README.md
    └── ios
       └── README.md
    
  • sidebarDepth:嵌套的标题链接深度,默认的深度为1。
  • lastUpdated:最后更新时间。

侧边栏如图:

具体主题配置详情请看文档:主题配置

PWA配置

VuePress默认支持PWA配置的,需要在基本配置中开启serviceWorker。

module.exports = {
     serviceWorker: true,
}

然后再添加icons和Manifest配置,在public中添加manifest.json配置,和图标。如果不知道PWA的可以到PWA配置查看相关资料。

{
  "name": "姜帅杰",
  "short_name": "姜帅杰",
  "start_url": "index.html",
  "display": "standalone",
  "background_color": "#2196f3",
  "description": "姜帅杰的个人主页",
  "theme_color": "blue",
  "icons": [
    {
      "src": "./logo.png",
      "sizes": "144x144",
      "type": "image/png"
    }
  ],
  "related_applications": [
    {
      "platform": "web"
    },
    {
      "platform": "play",
      "url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb"
    }
  ]
}

在config.js配置中添加manifest.json,由于iphone11.3不支持manifest的图标,所以加上apple-touch-icon图标配置即可。

module.exports = {
    head: [
            ['link', { rel: 'manifest', href: '/manifest.json' }],
            ['link', { rel: 'apple-touch-icon', href: '/img/logo.png' }],
          ]
}

最后在iphone中访问网站,然后添加主屏幕即可。

自定义页面

默认的主题提供了一个首页(Homepage)的布局(用于这个网站的主页)。想要使用它,需要在你的根级 README.md的home: true,然后添加数据。

---
home: true
heroImage: /hero.png
actionText: 快速上手 →
actionLink: /zh/guide/
features:
- title: 简洁至上
  details: 以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。
- title: Vue驱动
  details: 享受 Vue + webpack 的开发体验,在 Markdown 中使用 Vue 组件,同时可以使用 Vue 来开发自定义主题。
- title: 高性能
  details: VuePress 为每个页面预渲染生成静态的 HTML,同时在页面被加载的时候,将作为 SPA 运行。
footer: MIT Licensed | Copyright © 2018-present Evan You
---

效果如下:

如果你想自定义首页或者其他页面,可以在页面的md文件中添加页面Vue文件。Vue文件放置在docs/.vuepress/components目录中。

---
layout: HomeLayout
---

例如我博客的自定义首页:

部署上线

由于构建的时候生成静态页面,所以将dist文件夹中的内容可以部署在gitHub的pages或者coding的pages都可以。如果使用git上传到github上,操作比较繁琐,这里使用脚本的方式自动部署到github上。

创建一个deploy.sh

在project下创建deploy.sh。

touch deploy.sh

编写脚本

#!/usr/bin/env sh

# 确保脚本抛出遇到的错误
set -e

# 生成静态文件
npm run docs:build

# 进入生成的文件夹
cd docs/.vuepress/dist

# 如果是发布到自定义域名
# echo 'www.example.com' > CNAME

git init
git add -A
git commit -m 'deploy'

# 如果发布到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master

# 如果发布到 https://<USERNAME>.github.io/<REPO>
# git push -f git@github.com:<USERNAME>/<REPO>.git master:gh-pages

cd -

设置package.json

{
    "scripts": {
        "deploy": "bash deploy.sh"
      },
}

运行npm run deploy 即可自动构建部署到github上。

详情请看,部署

示例:我的博客

查看原文

赞 120 收藏 85 评论 43

一念 收藏了文章 · 2018-09-26

JavaScript 初学者教程(指南)

一念 关注了标签 · 2018-09-03

spring

Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。

关注 24634

认证与成就

  • 获得 26 次点赞
  • 获得 3 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 3 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-11-03
个人主页被 362 人浏览