為了提升使用者體驗,今天我們來對
jeremy-ui
官網做一個優化 ?返回閱讀列表點選 這裡
Markdown 解析支援 ?️
習慣用 markdown
語法編輯,所以我們增加專案原始碼對 markdown
的支援,雖然即便這樣做依然無法和 JeremyPress 或者 VuePress 相比,但是至少不用糾結於原生 html
了,能夠在一定程度上解決排版問題。
我們需要增加一個 plugins
資料夾,並且在此資料夾下建立一個 md.ts
的檔案,程式碼如下:
import path from 'path'
import fs from 'fs'
import marked from 'marked'
const mdToJs = str => {
const content = JSON.stringify(marked(str))
return `export default ${content}`
}
export function md() {
return {
configureServer: [
async ({ app }) => {
app.use(async (ctx, next) => {
if (ctx.path.endsWith('.md')) {
ctx.type = 'js'
const filePath = path.join(process.cwd(), ctx.path)
ctx.body = mdToJs(fs.readFileSync(filePath).toString())
} else {
await next()
}
})
},
],
transforms: [{
test: context => context.path.endsWith('.md'),
transform: ({ code }) => mdToJs(code)
}]
}
}
應該看到,這裡我們需要依賴 marked
這個 npm
庫,執行專案之前,需要先安裝一下:
npm install marked --save
另外,我們還需要在專案的根目錄下建立 vite.config.ts
檔案,並對 markdown
外掛做一下配置:
import { md } from "./plugins/md";
export default {
plugins: [md()],
};
GitHub Markdown 樣式支援 ⛵
我們可以使用 github-markdown-css
這個庫來獲取樣式表
npm install github-markdown-css --save
安裝完成後,在 main.ts
中引入
import 'github-markdown-css'
最後,我們對 Guidance.vue
做下配置以便 markdown
檔案以及 markdown
樣式能夠在專案中被正確的解析:
<template>
<article class="markdown-body" v-html="md"></article>
</template>
<script>
import { ref } from "vue";
export default {
props: {
path: {
type: String,
required: true,
},
},
setup(props) {
const md = ref(null);
import(`../markdown/${props.path}.md`).then(
(res) => (md.value = res.default)
);
return { md };
},
};
</script>
程式碼展示 ?
參考 ElementUI 手冊,我們發現不僅展示了元件,還會給出例子所使用的程式碼,我們也在官網中增加檢視程式碼的功能。
我們可以在 vite
初始化的時候配置,即在 vite.config.ts
檔案中做配置:
// @ts-nocheck
import { md } from "./plugins/md";
import fs from 'fs'
import { baseParse } from '@vue/compiler-core'
export default {
base: '/',//指定打包後檔案的預設引用路徑
assetsDir: 'assets',
plugins: [md()],
vueCustomBlockTransforms: {
example: (options) => {
const { code, path } = options
const file = fs.readFileSync(path).toString()
const parsed = baseParse(file).children.find(n => n.tag === 'example')
const title = parsed.children[0].content
const main = file.split(parsed.loc.source).join('').trim()
return `export default function (Component) {
Component.__sourceCode = ${JSON.stringify(main)
}
Component.__sourceCodeTitle = ${JSON.stringify(title)}
}`.trim()
}
}
};
注意
這裡我們通過
// @ts-nocheck
註釋,來忽略靜態報錯
程式碼高亮顯示支援 ?️?
我們可以用 prismjs
庫來獲得程式碼高亮,先安裝
npm install prismjs --save
然後,再在需要使用的地方,分別引入 prismjs
和 prismjs/themes/prism.css
,即可開始使用
prismjs
的工作原理,是構造一個物件,並繫結到 window
上,所以在模板中使用的時候,需要先獲取 window.Prism
,再在 setup
中 return
出去。Prism
物件的常見用例如下:
Prism.highlight(
[sourceCode],
Prism.languages.html,
'html'
)
該物件上提供一個名為 highlight
的方法,該方法要求傳入 3 個引數,按順序分別如下
- 原始碼
- 作為程式碼進行解析
- 作為程式碼進行顯示(渲染)
最後,我們再在 Content.vue
檔案中配置 Prism
以便內容中涉及到程式碼的部分都能被高亮的顯示:
<template>
<h1>{{ title }}</h1>
<br />
<div
class="container"
v-for="({ ...component }, index) in components"
:key="index"
>
<jeremy-card class="example">
<h2>{{ component.__sourceCodeTitle }}</h2>
<br />
<component :is="component" />
<br />
<br />
<code class="markdown-body">
<pre
v-if="visibility[index]"
v-html="
Prism.highlight(
component.__sourceCode,
Prism.languages.html,
'html'
)
"
></pre>
</code>
<button class="toggle" @click="toggle(index)">
<span class="close" v-if="visibility[index]">
△
<span class="desp">隱藏程式碼</span>
</span>
<span class="open" v-else>
▽
<span class="desp">顯示程式碼</span>
</span>
</button>
</jeremy-card>
<br />
</div>
<jeremy-table bordered>
<thead>
<tr>
<th v-for="(head, index) in heads" :key="index">{{ head.name }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(attribute, index) in attributes" :key="index">
<td v-for="key in keys" :key="key" v-html="attribute[key]"></td>
</tr>
</tbody>
</jeremy-table>
</template>
<script lang="ts">
import JeremyButtons from "../components/contents/Button";
import JeremyCards from "../components/contents/Card";
import JeremyDialogs from "../components/contents/Dialog";
import JeremyInputs from "../components/contents/Input";
import JeremySwitchs from "../components/contents/Switch";
import JeremyTables from "../components/contents/Table";
import JeremyTabss from "../components/contents/Tabs";
import { ref } from "vue";
import { JeremyCard, JeremyTable } from "jeremy-ui"
import "prismjs";
const Prism = (window as any).Prism;
const JeremyMap = {
Button: JeremyButtons,
Card: JeremyCards,
Dialog: JeremyDialogs,
Input: JeremyInputs,
Switch: JeremySwitchs,
Table: JeremyTables,
Tabs: JeremyTabss,
};
export default {
props: {
name: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
},
components: {
JeremyCard,
JeremyTable,
},
setup(props) {
const { name, title } = props;
const heads = [
{ name: "引數", identifier: "attr" },
{ name: "含義", identifier: "desp" },
{ name: "型別", identifier: "type" },
{ name: "可選值", identifier: "values" },
{ name: "預設值", identifier: "default" },
];
const keys = heads.map((item: any) => item.identifier);
const { components, attributes } = JeremyMap[name];
const visibility = ref(components.map((item) => false));
const toggle = (index) => {
visibility.value[index] = !visibility.value[index];
};
return {
title,
Prism,
heads,
keys,
components,
attributes,
visibility,
toggle,
};
},
};
</script>
另外,我們還需要在 main.ts
中引入程式碼樣式:
import "prismjs/themes/prism-solarizedlight.css"
注意
樣式可以根據自己的喜好進行選擇,我這裡選的是
prism-solarizedlight
除此之外,檢視
prism
主題包可以看到其他的樣式哦
展開/關閉程式碼 ?
通過一個開關事件去控制程式碼的顯示和隱藏
需要在 Content.vue
檔案中配置一下:
<button class="toggle" @click="toggle(index)">
<span class="close" v-if="visibility[index]"> △
<span class="desp">隱藏程式碼</span>
</span>
<span class="open" v-else>
▽
<span class="desp">顯示程式碼</span>
</span>
</button>
修改 UI 引用路徑 ?
官網的 UI
框架引用改成來自 npm
,這樣能夠更好的提升使用者體驗。先安裝:
npm install jeremy-ui --save
再在 main.ts
中引用樣式表:
import 'jeremy-ui/lib/jeremy.css'
最後,修改每個例子中的引用即可。
效果展示 ?
專案地址 ?
GitHub: https://github.com/JeremyWu917/jeremy-ui
官網地址 ?
JeremyUI: https://ui.jeremywu.top
感謝閱讀 ☕