商汇粹外网资源平台

搜索
查看: 2475|回复: 5

如何评价 VuePress?

[复制链接]

该用户从未签到

12

主题

56

帖子

181

积分

注册会员

Rank: 2

积分
181
发表于 2022-9-22 17:33:50 | 显示全部楼层 |阅读模式
Vue 作者于 2018 年 4 月 13 日推出基于  Vue、围绕 markdown 生成静态页面的 VuePress 框架。
回复

使用道具 举报

该用户从未签到

10

主题

50

帖子

151

积分

注册会员

Rank: 2

积分
151
发表于 2022-9-22 18:10:30 | 显示全部楼层
Vue Eco 的有力补充。
————— 下面不是评价
这种解决轻量需求的工具,一划拉一大把,大多没有本质区别,因为解决的本来就是标准问题,要不然也做不成工具,无非是不同的 approach。大多数人可能都会因为默认主题养眼就选了,就像用 Ghost 的人又有多少自己写过甚至换过 theme 呢?
至于
@林夕木木

这种人,你知道这是开源的吧?你知道屎一样的项目开源出来,社区是可以帮助完善的吧?你懒得动手或者根本没能力动手就算了,你知道你在这发牢骚的时候人家是没挣你钱的吧?你知道有人不满意的时候自己动手去改进而不是像你一样在这 crying like a baby 吧?
要饭还嫌馊?你配用开源软件吗?不理解开源,你配做工程师么?
回复

使用道具 举报

该用户从未签到

3

主题

56

帖子

194

积分

注册会员

Rank: 2

积分
194
发表于 2022-9-22 18:47:10 | 显示全部楼层
今天刚看到,体验了一下,跟几个类似的工具(docsify,gitbook),做个对比
1 配置 docsify >> gitbook = vuepress
由于docsify不需要编译,他的配置比另外两个简单很多,而另外两个,从文档看差距不大
2 阅读体验 gitbook > docsify = vuepress
这里不讨论UI,只说阅读体验,gitbook可以调节背景字体大小等,阅读体验上更佳
3 UI vuepress = docsify > gitbook
主观感受,没什么好说的
4 性能 vuepress > docsify = gitbook
单页预编译明显效率最高,多页与运行时编译,难说谁强,一样吧
5 灵活性 vuepress > docsify >> gitbook
由于vue的特点,灵活性方面十分优秀
6 导出 gitbook > ??
只有gitbook带有导出PDF的功能(虽然很差),但如果您需要使用PDF做个备份的情况呢
7 搜索 gitbook > docsify > vuepress
对于文档来说搜索虽说是一个功能模块,但却很重要,gitbook插件最多最佳,docsify默认的全文搜索挺不错的,vuepress默认只能搜索标题,全文需要引用第三方的工具
8 seo gitbook = vuepress >> docsify
具体使用哪个,需要看自己的情况做决定,例如vue文档,对他来说,配置导出之类并不重要,灵活性seo等更加重要,而本身vue文档只想标题搜索。所以vuepress非常适合
对于企业内部文档,个人认为配置是十分重要的一项(并不止前端用),docsify更适合
gitbook对标书本,他更注重阅读体验


﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉
分割,更新于2019年第一天
由于gitbook团队不再维护cli,所以不推荐使用gitbook(不清楚再搞什么)


另外Hexo + Theme NexT,算另一个文档方案,hexo本身属于博客系统,对于新版本发布文章更友好,而最受欢迎的next主题,目前支持三级菜单,对于文档来说,也不算差了


除此之外,react那边视乎也有竞品,但我不熟悉
回复

使用道具 举报

该用户从未签到

1

主题

33

帖子

131

积分

注册会员

Rank: 2

积分
131
发表于 2022-9-22 19:23:50 | 显示全部楼层
Vue 生态的又一工具。

充分利用了 vue、vue-router,vue ssr 等技术,其实只是想让会vue的人更快捷地写文档罢了。
它的核心理念是这样的:
对于文档编写者来说,一切皆 markdown,这样就可以专心于文档内容了。
而对于文档开发者来说,一切皆 vue 组件,这样就可以用已有技能做更多的事情了。比如自定义主题等。
为什么可以这样做?因为源码里形成了一个 YAML - Markdown - HTML - Vue - SSR 静态页面的管道。我认为设计的非常棒。
当然尤雨溪本人也说了...做这个东西原本只是想解决他自己写文档麻烦的痛点而已。
回复

使用道具 举报

该用户从未签到

6

主题

81

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
发表于 2022-9-22 20:00:30 | 显示全部楼层
前言

作为一个程序员,没有折腾过个人博客是不算完整的。技术文章的输出是我们程序员能力的一种体现,也是一种非常好的个人总结。
市面上有很多搭建个人博客的工具或框架,包括hexo、wordpress等等。不可否认,市面上有些博客系统做得很好,博客主题也很丰富,但是往往存在一个问题:比较重。
作为一个Vue程序员,我就比较推荐使用vuepress搭建个人博客,因为它毕竟是Vue出品的,大家熟知的vue官方就是利用vuepress搭建的。
本篇文章就从零开始教大家搭建一个免费的博客,零基础小白也可以学习哦!
1. 什么是Vuepress?

Vuepress是官方出品的一款极简静态网站生成器,它的初衷就是为了用于方便快速的撰写文档。
它主要包含了以下几个特点:

  • 非常简洁
  • 良好的SEO
  • 加载性能很高
  • 可自定义主题
  • 可以在markdown中写vue组件
上面几点主要是Vuepress比较突出的几个特点。对于博客网站SEO无疑是非常重要的,要是我们写的文章没人看,很容易失去动力的,Vuepress有着良好的SEO,除此之外,它对于有Vue基础的小伙伴是很友好的,我们自定义主题或者组件都是非常方便的,市面上的一些博客系统虽然也支持自定义主题,但是往往改起来比较费劲,需要下功夫学习。
我们来看下Vuepress官网:Vuepress

2. 准备工作

今天我们搭建的这个博客无需花费一分钱,全程免费!所需要准备的东西也是很少的!
基础环境:

  • 电脑安装了git
  • 电脑具有Node环境
  • VScode编辑器(可选)
  • gitee账号
我们的准备工作非常的简单,如果你是程序员,上面的几个环境和软件相信我不用多说,可以直接跳到第3节去。如果你是小白,那么我们先把环境搭建好即可。
环境搭建步骤:
2.1 node安装

去Node官网下载安装包:Node官网
选择自己电脑合适的版本安装即可,安装过程一直下一步。

2.2 git安装

去git官网下载安装包:git官网
选择自己电脑合适的版本安装即可,安装过程一直下一步。

2.3 gitee账号注册

到gitee官网注册一个账号一个,待会儿我们会把博客网站部署到gitee上面:git官网

3. 搭建步骤

3.1 初始化Vuepress

第一步:
在电脑任意位置创建文件夹,用于存放我们的博客系统,我这里新建了一个blog文件夹,如下图:

第二步:
在blog文件夹下打开命令行工具,如果安装了git,鼠标右键菜单里面会有git菜单,点击git bash here:


第三步:
先检查下node是否安装好,执行命令:
node -v

出现版本号则安装成功。
然后在blog文件夹下利用npm初始化,执行命令:
npm init -v


第三步:
安装vuepress,执行命令:
npm install -D vuepress

由于网络可能安装会比较慢,耐心等待即可,失败的话重新多安装几次,出现上述界面则代表安装成功。

3.2 初始化目录

第一步:
在blog文件夹下新建docs目录,然后在目录下新建README.md文件作为我们博客的首页,doc目录用于存放我们的文章和相关配置文件。

然后修改README.md内容,具体的配置项目可参考官网:配置项
---home: trueheroText: 一个分享各类资源的地方tagline: 公众号:资料分享大师actionText: 查看资源 →actionLink: /软件资源/软件资源features:- title: 网盘资源  details: 所有网盘资源均来自互联网,本网站不生产任何网盘资源,网盘资源是否失效需要自行判断。- title: 黑科技软件  details: 主要分享一些实用性的工具类、影视类、音乐类等等各种软件,均由互联网大佬提供。- title: 教程资源  details: 分享各类教程,包括编程、各类证书考试资源等等,本网站所有教程资源均来自互联网,若涉及侵权立马删除!footer: 科技趣玩 | 资料分享大师---
第二步:
修改package.json文件,该文件用于我们项目的打包和运行,修改后的代码如下:
{  "name": "blog",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "dev": "vuepress dev docs",    "build": "vuepress build docs"  },  "keywords": [],  "author": "",  "license": "ISC",  "devDependencies": {    "vuepress": "^1.9.7"  }}
第三步:
执行命令,将博客运行起来看看效果,执行命令:
npm run dev
出现如下界面则代表运行成功:

点击链接访问:http://localhost:8080/

我们一个最简单的博客就搭建成功了。
3.3 编写文章

大家可以仔细看看README.md文件内容中有一个actionLink字段,这表示我们点击首页的按钮跳转到哪个页面。
在docs目录下新建”软件资源“文件夹,然后在文件夹内新建”软件资源.md“文件,然后编写内容:

点击首页按钮,跳转访问效果如下:

3.4 添加侧边栏

虽然我们文章添加了,但是没有侧边栏,我们需要修改一些配置文件。
在docs文件夹下新建.vuepress文件夹,然后在此文件夹下新建config.js,用于配置我们的博客相关配置,编写代码如下:
// docs/.vuepress/config.jsmodule.exports = {  title: "科技趣玩",  description: "分享各类资源、教程、黑科技软件、工具等等",  markdown: {    lineNumbers: true,  },  themeConfig: {    sidebar: [      {        title: '软件资源',        children: ['/软件资源/软件资源' ],        initialOpenGroupIndex: 1 // 可选的, 默认值是 0      }    ]  },};
其中themeConfig属性中的sidebar字段就是用来配置我们的侧边栏的,具体配置项可参考官网。
效果如下:

虽然侧边栏有了,但是似乎标题不大对劲,这是因为侧边栏取的是文章的标题,因为我们的文章没有写标题,所以稍微改造一下软件资源.md:

效果如下:

4. 更换主题

上面的步骤已经让我们搭建出了一个最简单的博客系统了,就和Vue官网长得差不多,可能有些小伙伴不太喜欢,所以我们可以取网上找一个好看的主题改一下。
比如我们就是用下图的这种主题:

主题官网:主题
在blog目录下执行命令:
npm install vuepress-theme-reco --save-dev
然后在.vuepress/config.js文件中配置主题,代码如下:
module.exports = {  title: "科技趣玩",  description: "分享各类资源、教程、黑科技软件、工具等等",  theme: 'reco',  markdown: {    lineNumbers: true,  },  // themeConfig: {  //   sidebar: [  //     {  //       title: '软件资源',  //       children: ['/软件资源/软件资源' ],  //       initialOpenGroupIndex: 1 // 可选的, 默认值是 0  //     }  //   ]  // },};
这个时候我们的博客就好看了一些了,当然了,如果还要更加个性化,建议去主题的官网认真查看各种配置规则。

5. 部署到gitee

我们本地把博客大致弄好之后,就要去部署了,让所有人都可以访问,这里我们就借助gitee来实现这一步。
5.1 新建仓库

在gitee上面我们新建一个仓库,用于存放我们的博客系统。

这里有一点两点需要注意:

  • 仓库名称建议与个人空间地址保持一致,这样就可以就可以通过个人[空间地址.http://gitee.io]的形式访问了。
  • 仓库私有或者共有根据个人情况而定。
个人空间地址设置:

仓库创建成功后如下图:

5.2 推送至gitee

仓库建好后,就需要将我们本地的博客系统推送至仓库。
第一步:
进入blog目录,打开打开gitbash命令行工具,打包博客,执行命令:
npm run build

第二步:
我们可以参考gitee仓库给我们的步骤操作,将代码推送到仓库。
逐行执行下列命令:
git initgit add .git commit -m "初始化"git remote add origin https://gitee.com/sharemore52/myblog-demo.gitgit push -u origin "master"
执行完上面的命令后,我们的代码就推到了仓库中去:

5.3 部署

在仓库页面点击服务菜单,选择gitpage选项:

选择部署分支和部署目录,然后点击启动:

  • 部署分支,不用改,默认master
  • 部署目录,选择docs/.vuepress/dist文件夹,刚刚我们执行打包命令生成的。

部署好后就会出现一个我们的博客地址了,访问试试:

5.4 修改配置文件

可以看到我们上面访问的页面似乎出问题了,不要着急,只是我们项目配置的相关问题,我们在config.js文件中新增一段代码:
base: "./"
然后重新打包,部署,依次执行下面的命令:
npm run buildgit add .git commit -m "修改"git push
仓库中的代码更新后,我们重新进入gitpage目录,重新启动,这个时候就能正常访问了:

6. 常见问题解答

6.1 仓库是否可以私有?

可以的
6.2 博客地址为何多了一个路径?

像这种:https://sharemore52.gitee.io/myblog-demo/
仓库名和个人空间地址一样即可
6.3 如何做侧边栏自动化生成?

可以使用插件:vuepress-plugin-autobar
官网:官网
总结

到这里我们基本上就搭建好了个人博客,可以尽情的写文章了,总结一下大致分为以下几步:

  • 安装vuepress
  • 根据vuepress官网创建目录
  • 创建gitee仓库
  • 推送代码到gitee仓库
  • 使用giteepages部署
本篇文章只介绍了如何搭建博客,如果想要让自己的博客丰富起来,一点要去官网看各种配置项规则,包括vuepress和自定义主题的官网。
回复

使用道具 举报

该用户从未签到

6

主题

81

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
发表于 2022-9-22 20:37:10 | 显示全部楼层
提起帮助文档,想必大家都会想到 VuePress等,我也体验了一下,但是感觉和我的思路不太一样,我希望的是那种可以直接在线编辑文档,然后无需编译就可以直接发布的方式,另外可以在线写(修改)代码并且运行的效果。
VuePress 是“静态网站生成器”,需要我们自行编写文档,然后交给VuePress变成网站,VuePress 并没有提供编写环境,我知道有很多编写 Markdown 的方式,但是我还是喜欢编写、浏览合为“一体”的方式。
似乎没有,那么 —— 自己动手丰衣足食吧,开干!
技术栈


  • vite: ^2.7.0
  • vue: ^3.2.23
  • axios: ^0.25.0 获取json格式的配置和文档(CDN方式引入)
  • element-plus: ^2.0.2 UI库
  •   nf-ui-elp": ^0.1.0 二次封装的UI库
  •   @element-plus/icons-vue: ^0.2.4 图标
  •   @kangc/v-md-editor:"^2.3.13 md 编辑器
  • vite-plugin-prismjs: ^0.0.8 代码高亮
  • nf-state": ^0.2.4 状态管理
  • nf-web-storage": ^0.2.3 访问 indexedDB
建立库项目(@naturefw/press-edit)实现文档的编写、浏览功能

首先使用 vite2 建立一个 Vue3 的项目:

  • 安装 elementPlus 实现页面效果;
  • 安装 v-md-editor 实现 Markdown 的编辑和显示;
  • 安装 @naturefw/storage 操作 indexedDB ,实现帮助文档的存储;
  • 安装 @naturefw/nf-state 实现状态管理;
  • 安装axios 用于加载 json文件,实现导入功能。
  • 用node写一个后端API,实现写入json文件的功能。
注意:库项目需要安装以上插件,帮助文档项目只需要安装 @naturefw/press-edit 即可。
基本功能就是这样,心急的可以先看在线演示和源码。

  • 在线演示:


  • 源码:


  • 编辑页面


  • 浏览页面

两个状态:编辑和浏览

一开始做了两个项目,分别实现编辑文档和显示文档的功能,但是后来发现,内部代码大部分是相同的,维护的时候有点麻烦,所以改为在编辑文档的项目里加入“浏览”的状态,然后设置切换的功能,这样便于内部代码的维护,以后成熟了可能会分为两个单独的项目。
编辑状态的功能


  • 菜单维护
  • 文档维护
  • 文档展示
  • 导入导出
  • 在线编写/执行代码
我喜欢在线编辑的方式,这样更省心,于是我用 el-menu 实现导航和左侧的菜单,然后加上了维护功能。使用 v-md-editor 实现  Markdown 的编辑和显示。然后用node写了一个后端API,实现保存 json文件的功能,这样就完美了。
浏览状态的功能


  • 导航
  • 菜单
  • 文档展示
  • 执行代码
就是在编辑状态的功能的基础上,去掉一些功能。或者其实可以反过来思考。
实现导航

首先参考 VuePress 设置一个json文件,用于加载和保存网站信息、导航信息。
/public/docs/.nfpress/project.json
{  "projectId": "1000",  "title": "nf-press-edit !",  "description": "这是一个在线编辑、展示文档的小工具",  "navi": [    {      "naviId": "1010",      "text": "指南",      "link": "menu"    },    {      "naviId": "1020",      "text": "组件",      "link": "menu"    },    {      "naviId": "1380",      "text": "Gitee",      "link": "帮助文档/nf-press-edit_帮助文档的管理平台"    },    {      "naviId": "1390",      "text": "在线演示",      "link": "在线编写帮助文档"    },    {      "naviId": "1395",      "text": "我要提意见",      "link": "Issues · 帮助文档/nf-press-edit_帮助文档的管理平台 - Gitee.com"    }  ]}

  • projectId:项目ID,可以用于区分不同的帮助文档项目。
  • navi: 存放导航项。
  • naviId: 关联到菜单。
  • text: 导航上显示的文字。
  • link: 连接方式或链接地址。menu:表示要打开对应的菜单;URL:在新页面里打开连接。
然后做一个组件,用 el-menu 绑定数据渲染出来即可实现导航效果。
/lib/navi/navi.vue
<el-menu    :default-active="activeIndex2"    class="el-menu-demo"    mode="horizontal"    v-bind="$attrs"    :background-color="backgroundColor"    @select="handleSelect"  >    <el-menu-item      v-for="(item, index) in naviList"      :key="index"      :index="item.naviId"    >      {{item.text}}    </el-menu-item>  </el-menu>
可以是多级的导航,暂时没有实现在线维护功能。


  import { ref } from 'vue'  import { ElMenu, ElMenuItem } from 'element-plus'  import { state } from '@naturefw/nf-state'     const props = defineProps({    'background-color': { // 默认背景色      type: String,      default: '#ece5d9'    },    itemProps: Object  })  // 获取状态和导航内容  const { current, naviList } = state  // 激活第一个导航项  const activeIndex2 = ref(naviList[0].naviId)    const handleSelect = (key, keyPath) => {    const navi = naviList.find((item) => item.naviId === key)    if (navi.link === 'menu') {      // 打开菜单      current.naviId = key    } else {      // 打开连接      window.open(Navi Link, '_blank')    }  }

  •   @naturefw/nf-state
自己写的一个轻量级状态管理,可以当做大号 reactive 来使用,通过状态管理加载 project.json 然后绑定渲染。

  • naviList
导航列表,由状态管理加载。

  • current
当前激活的各种信息,比如“current.naviId”表示激活的导航项。
实现菜单

和导航类似,只是需要增加两个功能:n级分组和维护。
首先参考 VuePress 设置一个json文件,保存菜单信息。
/public/docs/.nfpress/menu.json
[  {    "naviId": "1010",    "menus": [      {        "menuId": "110100",        "text": "介绍",        "description": "描述",        "icon": "FolderOpened",        "children": []      },      {        "menuId": "111100",        "text": "快速上手",        "description": "描述",        "icon": "FolderOpened",        "children": [          {            "menuId": 111120,            "text": "编辑文档项目",            "description": "",            "icon": "UserFilled",            "children": []          },          {            "menuId": 111130,            "text": "展示文档项目",            "description": "",            "icon": "UserFilled"          }        ]      }     ],    "ver": 1.6  },  {    "naviId": "1020",    "menus": [      {        "menuId": "21000",        "text": "导航(docNavi)",        "description": "描述",        "icon": "Star",        "children": []      }     ],    "ver": 1.5  }]

  • naviId:  关联导航项ID,可以是数字,也可以是其他字符。需要和导航项ID对应。
  • menus: 导航项对应的菜单项集合。
  • menuId: 菜单项ID,关联一个文档,可以是数字或者英文。
  • text: 菜单项名称。
  • description: 描述,考虑以后用于查询。
  • icon: 菜单使用的图标名称。
  • children: 子菜单项目,没有的话可以去掉。
  • ver: 版本号,便于更新文档。
然后用  el-menu 绑定数据渲染,因为要实现n级分组,所以做一个递归组件实现n级菜单的效果。


实现n级分组菜单

做一个递归组件实现n级分组的功能:
/lib/menu/menu-sub-edit.vue
<template v-for="(item, index) in subMenu">    <!--树枝-->    <template v-if="item.children && item.children.length > 0">      <el-sub-menu         :key="item.menuId + '_' + index"        :index="item.menuId"        style="vertical-align: middle;"      >        <template #title>          <div style="display:inline;width: 100%;">            <component              :is="$icon[item.icon]"              style="width: 1.5em; height: 1.5em; margin-right: 8px;vertical-align: middle;"            >            </component>            <span>{{item.text}}</span>          </div>        </template>        <!--递归子菜单-->        <my-sub-menu2          :subMenu="item.children"          :dialogAddInfo="dialogAddInfo"          :dialogModInfo="dialogModInfo"        />      </el-sub-menu>    </template>    <!--树叶-->    <el-menu-item v-else      :index="item.menuId"      :key="item.menuId + 'son_' + index"    >      <template #title>        <div style="display:inline;width: 100%;">          <span style="float: left;">            <component              :is="$icon[item.icon]"              style="width: 1.5em; height: 1.5em; margin-right: 8px;vertical-align: middle;"            >            </component>            <span >{{item.text}}</span>          </span>        </div>      </template>    </el-menu-item>  </template>
  import { ElMenuItem, ElSubMenu } from 'element-plus'  // 展示子菜单 - 递归  import mySubMenu2 from './menu-sub.vue'  const props = defineProps({    subMenu: Array, // 要显示的菜单,可以n级    dialogAddInfo: Object, // 添加菜单    dialogModInfo: Object // 修改菜单  })

  • subMenu 要显示的子菜单项
  • dialogAddInfo 添加菜单的信息
  • dialogModInfo 修改菜单的信息


实现菜单的维护功能

这个就比较简单了,做个表单实现菜单的增删改即可,篇幅有限跳过。
实现 Markdown  的编辑

使用 v-md-editor 实现  Markdown  的编辑和展示,首先该插件非常好用,其次支持VuePress的主题。
建立 /lib/md/md-edit.vue 实现编辑  Markdown 的功能:
  <v-md-editor    :toolbar="toolbar"    left-toolbar="undo redo clear | tip emoji code | h bold italic strikethrough quote | ul ol table hr | link image  | save | customToolbar"    :include-level="[1, 2, 3, 4]"    v-model="current.docInfo.md"    :height="editHeight + 'px'"    @save="mySave"  >  </v-md-editor>


import { watch,ref  } from 'vue'  import { ElMessage, ElRadioGroup, ElRadioButton } from 'element-plus'  import mdController from '../service/md.js'    // 状态  import { state } from '@naturefw/nf-state'  // 获取当前激活的信息  const current = state.current  // 文档的加载和保存  const { loadDocById, saveDoc } = mdController()    // 可见的高度  const editHeight = document.documentElement.clientHeight - 200  // 单击 保存 按钮,实现保存功能  const mySave = (text, html) => {    saveDoc(current)  }  // 定时保存  let timeout = null  let isSaved = true  const timeSave = () => {    if (isSaved) {      // 保存过了,重新计时      isSaved = false    } else {      return // 有计时,退出    }    timeout = setTimeout(() => {      // 保存文档      saveDoc(current).then(() => {        ElMessage({          message: '自动保存文档成功!',          type: 'success',        })      })      isSaved = true    }, 10000)  }  // 定时保存文档  watch(() => current.docInfo.md, () => {    timeSave()  })  // 根据激活的菜单项,加载对应的文档  watch( () => current.menuId, async (id) => {    const ver = current.ver    loadDocById(id, ver).then((res) => {      // 找到了文档      Object.assign(current.docInfo, res)    }).catch((res) => {      // 没有文档      Object.assign(current.docInfo, res)    })  })

  • mdController 实现文档的增删改查的controller
  • timeSave 定时保存文档,避免忘记点保存按钮
是不是挺简单的。


实现在线编写代码并且运行的功能

因为是基于Vue3建立的项目,而且也是为了写vue3相关的帮助文档,那么就有一个很实用的要求:在线写代码并且可以运行
个人感觉这个功能还是很实用的,我知道有第三方网站提供了这种功能,但是网速有点慢,另外有一种大炮打蚊子的感觉,我只需要实现简单的代码演示。
于是我基于 vue 的 defineAsyncComponent 写了一个简单版的在线编写代码且运行的功能:
/lib/runCode/run.vue
<div style="padding: 5px; border: 1px solid #ccc!important;">    <async-comp></async-comp>  </div>
  import {    defineAsyncComponent,    ref, reactive,...    // 其他常用的vue内置指令  } from 'vue'  // 使用 eval编译js代码  const mysetup = `    (function setup () {      {{code}}    })  `    // 通过属性传入需要运行的代码和模板  const props = defineProps({    code: {      type: Object,      default: () => {        return {          js: '',          template: '',          style: ''        }      }    }  })  const code = props.code  // 使用 defineAsyncComponent 让代码运行起来  const AsyncComp = defineAsyncComponent(    () => new Promise((resolve, reject) => {        resolve({          template: code.template, // 设置模板          style: [code.style], // 大概是样式设置,但是好像没啥效果          setup: (props, ctx) => {            const tmpJs = code.js // 获取js代码            let fun = null // 转换后的函数            try {              if (tmpJs)                fun = eval(mysetup.replace('{{code}}', tmpJs)) // 用 eval 把 字符串 变成 函数            } catch (error) {              console.error('转换出现异常:', error)            }            const re = typeof fun === 'function' ? fun : () => {}            return {              ...re(props, ctx) // 运行函数,解构返回对象            }          }        })      })  )

  • defineAsyncComponent
实用 defineAsyncComponent 加载组件,需要设置三个部分:模板、setup和style。

  • template: 字符串形式,可以直接传入
  • setup: js代码,可以用eval的方式进行动态编译。
  • style: 可以设置样式。
这样即可让在线编写的代码运行起来,当然功能有限,只能用于一些简单的代码演示。


导出

以上这些功能都是基于 indexedDB 进行的,想要发布的话,需要先导出为json文件。
因为浏览器里不能直接写文件,所以需要使用折中的方式:

  • 复制粘贴
  • 下载
  • 导出


复制粘贴

这个简单,用文本域显示json即可。
下载

使用 chrome 浏览器提供的下载功能下载文件。
const uri = 'data:text/json;charset=utf-8,\ufeff' + encodeURIComponent(show.navi)  //通过创建a标签实现  var link = document.createElement("a")  link.href = uri  //对下载的文件命名  link.download = fileName  document.body.appendChild(link)  link.click()  document.body.removeChild(link)
以上介绍的是内部原理,如果只是想简单使用的话,可以跳过,直接看下面的介绍。


用后端写文件

以上两种都不太方便,于是用node做了个简单的后端API,用于实现写入json文件的功能。
代码放在了 api文件夹里,可以使用 ```yarn api```运行。当然需要在 package.json 里做一下设置。
"scripts": {    "dev": "vite",    "build": "vite build --mode project",    "lib": "vite build --mode lib",    "serve": "vite preview",    "api": "node api/server.js"  },
实现一个帮助文档的项目

上面介绍的是库项目的基本原理,我们要做帮助文档的时候,并不需要那么复杂。
使用 vite2 建立一个vue3的项目,然后安装 @naturefw/press-edit,使用提供的组件即可方便的实现。
main.js

首先需要在 main.js 里面做一些设置。
import { createApp } from 'vue'import App from './App.vue'// 设置 axios 的 baseUrlconst baseUrl = (document.location.host.includes('.gitee.io')) ?  '/doc-ui-core/' :  '/'// 轻量级状态// 设置 indexedDB 数据库,存放文档的各种信息。import { setupIndexedDB, setupStore } from '@naturefw/press-edit'// 初始化 indexedDB 数据库setupIndexedDB(baseUrl)  // UI库import ElementPlus from 'element-plus'// import 'element-plus/lib/theme-chalk/index.css'// import 'dayjs/locale/zh-cn'import zhCn from 'element-plus/es/locale/lang/zh-cn'// 二次封装import { nfElementPlus } from '@naturefw/ui-elp'// 设置iconimport installIcon from './icon/index.js'// 设置 Markdown 的配置函数import setMarkDown from './main-md.js'// 主题import vuepressTheme from '@kangc/v-md-editor/lib/theme/vuepress.js'const {  VueMarkdownEditor, // Markdown 的编辑器  VMdPreview // Markdown 的浏览器} = setMarkDown(vuepressTheme)const app = createApp(App)app.config.globalProperties.$ELEMENT = {  locale: zhCn,  size: 'small'}app.use(setupStore) // 状态管理  .use(nfElementPlus) // 二次封装的组件  .use(installIcon) // 注册全局图标  .use(ElementPlus, { locale: zhCn, size: 'small' }) // UI库  .use(VueMarkdownEditor) // markDown编辑器  .use(VMdPreview) // markDown 显示  .mount('#app')

  • baseUrl: 根据发布平台的情况进行设置,比如这里需要设置为:“/doc-ui-core/”
  • setupIndexedDB:  初始化 indexedDB 数据库
  • setupStore: 设置状态
  • element-plus:element-plus 可以不挂载,但是css需要 import 进来,这里采用CDN的方式引入。
  • nfElementPlus: 二次封装的组件,便于实现增删改查。
  • setMarkDown: 加载 v-md-editor ,以及需要的插件。
  • vuepressTheme: 设置主题。
设置 Markdown

因为 v-md-editor  相关设置比较多,所以设置了一个单独文件进行管理:
/src/main-md.js
// Markdown 编辑器import VueMarkdownEditor from '@kangc/v-md-editor'import '@kangc/v-md-editor/lib/style/base-editor.css'// 在这里引入,不被识别?// import vuepressTheme from '@kangc/v-md-editor/lib/theme/vuepress.js'import '@kangc/v-md-editor/lib/theme/style/vuepress.css'// 代码高亮import Prism from 'prismjs'// emojiimport createEmojiPlugin from '@kangc/v-md-editor/lib/plugins/emoji/index'import '@kangc/v-md-editor/lib/plugins/emoji/emoji.css'// 流程图// import createMermaidPlugin from '@kangc/v-md-editor/lib/plugins/mermaid/cdn'// import '@kangc/v-md-editor/lib/plugins/mermaid/mermaid.css'// todoListimport createTodoListPlugin from '@kangc/v-md-editor/lib/plugins/todo-list/index'import '@kangc/v-md-editor/lib/plugins/todo-list/todo-list.css'// 代码行号import createLineNumbertPlugin from '@kangc/v-md-editor/lib/plugins/line-number/index';// 高亮代码行import createHighlightLinesPlugin from '@kangc/v-md-editor/lib/plugins/highlight-lines/index'import '@kangc/v-md-editor/lib/plugins/highlight-lines/highlight-lines.css'// 复制代码import createCopyCodePlugin from '@kangc/v-md-editor/lib/plugins/copy-code/index'import '@kangc/v-md-editor/lib/plugins/copy-code/copy-code.css'// markdown 显示器import VMdPreview from '@kangc/v-md-editor/lib/preview'// import '@kangc/v-md-editor/lib/style/preview.css'/** * 设置 Markdown 编辑器 和浏览器 * @param {*} vuepressTheme  * @returns  */export default function setMarkDown (vuepressTheme) {  // 设置 vuePress 主题  VueMarkdownEditor.use(vuepressTheme,    {      Prism,      extend(md) {        // md为 markdown-it 实例,可以在此处进行修改配置,并使用 plugin 进行语法扩展        // md.set(option).use(plugin);      },    }  )    // 预览  VMdPreview.use(vuepressTheme,    {      Prism,      extend(md) {        // md为 markdown-it 实例,可以在此处进行修改配置,并使用 plugin 进行语法扩展        // md.set(option).use(plugin);      },    }  )    // emoji  VueMarkdownEditor.use(createEmojiPlugin())  // 流程图  // VueMarkdownEditor.use(createMermaidPlugin())  // todoList  VueMarkdownEditor.use(createTodoListPlugin())  // 代码行号  VueMarkdownEditor.use(createLineNumbertPlugin())  // 高亮代码行  VueMarkdownEditor.use(createHighlightLinesPlugin())  // 复制代码  VueMarkdownEditor.use(createCopyCodePlugin())    // 预览的插件  VMdPreview.use(createEmojiPlugin())  VMdPreview.use(createTodoListPlugin())  VMdPreview.use(createLineNumbertPlugin())  VMdPreview.use(createHighlightLinesPlugin())  VMdPreview.use(createCopyCodePlugin())    return {    VueMarkdownEditor,    VMdPreview  }}


不多介绍了,可以根据需要选择插件。
布局

在App.vue文件里面进行整体布局
<el-container>    <el-header>      <!--导航-->      <div style="float: left;">        <!--写网站logo、标题等-->        <h1>nf-press</h1>      </div>      <div style="float: right;min-width: 100px;height: 60px;padding-top: 13px;">        <!--写网站logo、标题等-->        <el-switch v-model="$state.current.isView" v-bind="itemProps"></el-switch>      </div>      <div style="float: right;min-width: 600px;height: 60px;">        <!--网站导航-->        <doc-navi ></doc-navi>      </div>    </el-header>    <el-container>      <!--左侧边栏-->      <el-aside width="330px">        <!--菜单-->        <doc-menu ></doc-menu>      </el-aside>      <el-main>        <!--文档区域-->        <component          :is="docControl[$state.current.isView]"        />      </el-main>    </el-container>  </el-container>
  import { reactive, defineAsyncComponent } from 'vue'  import { ElHeader, ElContainer ,ElAside, ElMain } from 'element-plus'  import { docMenu, docNavi, config } from '@naturefw/press-edit' // 菜单 导航  import docView from './views/doc.vue' // 显示文档  // 加载菜单子控件  const docControl = {    true: docView,    false: defineAsyncComponent(() => import('./views/main.vue')) // 修改文档  }  const itemProps = reactive({    'inline-prompt': true,    'active-text': '看',    'inactive-text': '写',    'active-color': '#378FEB',    'inactive-color': '#EA9712'  })



  • \$state:全局状态,$state.current.isView 设置是否是浏览状态。
  • doc-navi:导航组件
  • doc-menu:菜单组件
  • docControl:根据状态选择加载显示组件或者编辑组件的字典。
这种方式虽然有点麻烦,但是比较灵活,可以根据需要进行各种灵活设置,比如添加版权信息、备案信息、广告等内容。
导航、菜单、编辑和浏览

直接使用组件实现,比较简单不搬运了,直接看源码即可。
打包发布与版本管理

需要打包的情况分为两种:第一次打包、修改代码(非在线编辑的代码)后打包。
如果只是文档内容有变化的话,只需要直接上传json文件即可,不需要再次打包。
内置了一个简单的版本管理功能,可以通过 ver.json文件里的版本号实现更新功能。
源码


在线演示




demo
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表