Skip to content

Commit 64f1fd3

Browse files
committed
基础代码示例解析完成
1 parent 10dc17c commit 64f1fd3

File tree

16 files changed

+841
-8
lines changed

16 files changed

+841
-8
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# 更新日志
2+
3+
- 修订版本号:修复 bug,代码调整,功能优化。
4+
- 次版本号:新增功组件或者新增功能。
5+
- 主版本号:含有破坏性更新和新特性。
6+
7+
## 0.1.0
8+
9+
`2020-04-15`
10+
11+
- 🎉 第一个组件示例

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,7 @@ module.exports = {
7878
}
7979
};
8080
```
81+
82+
npm i markdown-it markdown-it-container highlight.js -D
83+
84+
代码解析组件 vue

build/markdown-loader.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
const MarkdownIt = require("markdown-it");
2+
const MarkdownItContainer = require("markdown-it-container");
3+
const VueTemplateComplier = require("vue-template-compiler");
4+
const hljs = require("highlight.js");
5+
const { parse, compileTemplate } = require("@vue/component-compiler-utils");
6+
7+
module.exports = function(source) {
8+
// 需要解析成vue代码块集合
9+
const componentCodeList = [];
10+
let styleCodeList = [];
11+
const globalScript = [];
12+
// 初始还MarkdownIt用于转换md文件为html
13+
const markdownIt = MarkdownIt({
14+
html: true,
15+
xhtmlOut: true,
16+
// 将markdown中的代码块用hljs高亮显示
17+
highlight: function(str, lang) {
18+
if (lang && hljs.getLanguage(lang)) {
19+
return `<pre class="hljs"><code>${
20+
hljs.highlight(lang, str, true).value
21+
}</code></pre>`;
22+
}
23+
return `<pre class="hljs"><code>${markdownIt.utils.escapeHtml(
24+
str
25+
)}</code></pre>`;
26+
}
27+
});
28+
// 解析【:::tip:::】
29+
markdownIt.use(MarkdownItContainer, "tip");
30+
// 解析【:::warning:::】
31+
markdownIt.use(MarkdownItContainer, "warning");
32+
// 使用【markdown-it-container】插件解析【:::snippet :::】代码块为vue渲染
33+
markdownIt.use(MarkdownItContainer, "snippet", {
34+
// 验证代码块为【:::snippet :::】才进行渲染
35+
validate(params) {
36+
return params.trim().match(/^snippet\s*(.*)$/);
37+
},
38+
// 代码块渲染
39+
render(tokens, index) {
40+
const token = tokens[index];
41+
const tokenInfo = token.info.trim().match(/^snippet\s*(.*)$/);
42+
if (token.nesting === 1) {
43+
// 获取snippet第一行的表述内容
44+
const desc = tokenInfo && tokenInfo.length > 1 ? tokenInfo[1] : "";
45+
// 获取vue组件示例的代码
46+
const nextIndex = tokens[index + 1];
47+
let content = nextIndex.type === "fence" ? nextIndex.content : "";
48+
if (!/^<template>/.test(content)) {
49+
content = `<template><div>${content}</div></template>`;
50+
}
51+
52+
// 将content解析为vue组件基本属性对象;
53+
let { template, script, styles } = parse({
54+
source: content,
55+
compiler: VueTemplateComplier,
56+
needMap: false
57+
});
58+
styleCodeList = styleCodeList.concat(styles);
59+
// 将template的转为render函数
60+
const { code } = compileTemplate({
61+
source: template.content,
62+
compiler: VueTemplateComplier
63+
});
64+
// 获取script的代码
65+
script = script ? script.content : "";
66+
if (script) {
67+
const [global, content] = script.split(/export\s+default/);
68+
globalScript.push(global.trim());
69+
script = `const exportJavaScript = ${content}`;
70+
} else {
71+
script = "const exportJavaScript = {};";
72+
}
73+
// 代码块解析将需要解析vue组件的存储,渲染html用组件名称替代
74+
const name = `vc-snippent-${componentCodeList.length}`;
75+
// 渲染组件代码添加到数据集合
76+
componentCodeList.push(`"${name}":(function () {
77+
${code}
78+
${script}
79+
return {
80+
...exportJavaScript,
81+
render,
82+
staticRenderFns
83+
}
84+
})()`);
85+
// 将需要渲染的示例用vc-snippet组件包裹替换插槽显示示例效果
86+
return `<vc-snippet>
87+
<div slot="desc">${markdownIt.render(desc)}</div>
88+
<${name} slot="source" />
89+
<div slot="code">`;
90+
}
91+
return ` </div>
92+
</vc-snippet> `;
93+
}
94+
});
95+
// 将所有转换好的代码字符串拼接成vue单组件template、script、style格式
96+
return `
97+
<template>
98+
<div class="vc-snippet-doc">
99+
${markdownIt.render(source)}
100+
</div>
101+
</template>
102+
<script>
103+
${globalScript.join(" ")}
104+
export default {
105+
name: 'vc-component-doc',
106+
components: {
107+
${componentCodeList.join(",")}
108+
}
109+
}
110+
</script>
111+
<style lang='scss'>
112+
${Array.from(styleCodeList, m => m.content).join("\n")}
113+
</style>`;
114+
};

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-ui-docs",
3-
"version": "0.1.0",
3+
"version": "1.0.0",
44
"private": true,
55
"scripts": {
66
"serve": "vue-cli-service serve",
@@ -22,7 +22,10 @@
2222
"eslint": "^6.7.2",
2323
"eslint-plugin-prettier": "^3.1.1",
2424
"eslint-plugin-vue": "^6.2.2",
25+
"highlight.js": "^9.18.1",
2526
"lint-staged": "^9.5.0",
27+
"markdown-it": "^10.0.0",
28+
"markdown-it-container": "^2.0.0",
2629
"node-sass": "^4.12.0",
2730
"prettier": "^1.19.1",
2831
"sass-loader": "^8.0.2",
@@ -43,6 +46,9 @@
4346
},
4447
"rules": {}
4548
},
49+
"eslintIgnore": [
50+
"**/*.md"
51+
],
4652
"browserslist": [
4753
"> 1%",
4854
"last 2 versions",

site/App.vue

Lines changed: 218 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,225 @@
66

77
<style lang="scss">
88
#app {
9-
font-family: Avenir, Helvetica, Arial, sans-serif;
9+
font-family: Microsoft YaHei, -apple-system, BlinkMacSystemFont, "Segoe UI",
10+
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
1011
-webkit-font-smoothing: antialiased;
1112
-moz-osx-font-smoothing: grayscale;
1213
}
14+
15+
body,
16+
div,
17+
dl,
18+
dt,
19+
dd,
20+
ul,
21+
ol,
22+
li,
23+
h1,
24+
h2,
25+
h3,
26+
h4,
27+
h5,
28+
h6,
29+
pre,
30+
code,
31+
form,
32+
fieldset,
33+
legend,
34+
input,
35+
textarea,
36+
p,
37+
blockquote,
38+
th,
39+
td,
40+
hr,
41+
button,
42+
article,
43+
aside,
44+
details,
45+
figcaption,
46+
figure,
47+
footer,
48+
header,
49+
hgroup,
50+
menu,
51+
nav,
52+
section {
53+
margin: 0;
54+
padding: 0;
55+
}
56+
57+
html,
58+
body {
59+
width: 100%;
60+
height: 100%;
61+
color: #333333;
62+
font-size: 12px;
63+
}
64+
65+
ul,
66+
ol {
67+
list-style: none;
68+
}
69+
70+
a {
71+
color: #333333;
72+
text-decoration: none;
73+
background-color: transparent;
74+
outline: none;
75+
transition: color 0.3s;
76+
cursor: pointer;
77+
}
78+
79+
a:active,
80+
a:hover {
81+
text-decoration: none;
82+
outline: 0;
83+
}
84+
85+
.vc-snippet-doc {
86+
min-width: 600px;
87+
color: #3f536e;
88+
font-size: 14px;
89+
line-height: 1.5;
90+
91+
> .tip,
92+
> .warning {
93+
padding: 12px 16px;
94+
border-radius: 4px;
95+
margin: 20px 0;
96+
line-height: 1.3;
97+
}
98+
99+
> .tip {
100+
background-color: #ecf8ff;
101+
border-left: 5px solid #6190e8;
102+
}
103+
104+
> .warning {
105+
background-color: #fff6f7;
106+
border-left: 5px solid #fe6c6f;
107+
}
108+
109+
> h1 {
110+
font-size: 28px;
111+
font-weight: 600;
112+
margin: 22px 0 18px;
113+
}
114+
115+
> h2 {
116+
font-size: 22px;
117+
font-weight: 600;
118+
margin: 18px 0 10px;
119+
}
120+
121+
> h3 {
122+
font-size: 18px;
123+
font-weight: 600;
124+
margin: 15px 0 10px;
125+
}
126+
127+
> p {
128+
line-height: 1.8;
129+
color: #3f536e;
130+
font-size: 14px;
131+
margin-bottom: 5px;
132+
}
133+
134+
> p > code {
135+
background: #e6effb;
136+
border-radius: 3px;
137+
color: #5e6d82;
138+
padding: 2px 8px;
139+
}
140+
141+
> table {
142+
border-collapse: collapse;
143+
border-spacing: 0;
144+
empty-cells: show;
145+
border: 1px solid #ebedf0;
146+
width: 100%;
147+
margin: 8px 0 16px;
148+
font-size: 14px;
149+
150+
th,
151+
td {
152+
color: #314659;
153+
border: 1px solid #ebedf0;
154+
text-align: left;
155+
padding: 8px 10px;
156+
vertical-align: middle;
157+
158+
code {
159+
background: #e6effb;
160+
border-radius: 3px;
161+
color: #5e6d82;
162+
padding: 2px 8px;
163+
}
164+
}
165+
166+
th {
167+
white-space: nowrap;
168+
color: #333333;
169+
font-weight: 500;
170+
background-color: #fafafa;
171+
}
172+
}
173+
174+
> .hljs {
175+
padding: 0;
176+
}
177+
178+
> ol {
179+
> li {
180+
margin: 8px 0 8px 20px;
181+
padding-left: 0;
182+
list-style-type: decimal;
183+
line-height: 1.6;
184+
}
185+
}
186+
187+
code {
188+
background: #e6effb;
189+
border-radius: 3px;
190+
color: #5e6d82;
191+
padding: 2px 8px;
192+
}
193+
194+
a:not(.n-link) {
195+
text-decoration: none;
196+
color: #333333;
197+
}
198+
199+
h1,
200+
h2,
201+
h3,
202+
h4,
203+
h5,
204+
h6 {
205+
a.n-snippent--markdown-it-anchor {
206+
opacity: 0;
207+
}
208+
209+
&:hover a.n-snippent--markdown-it-anchor {
210+
opacity: 1;
211+
transition: opacity 0.3s;
212+
}
213+
}
214+
}
215+
216+
.hljs > code {
217+
border: 1px solid #f0f2f7;
218+
background: #f9f9f9;
219+
font-family: Consolas, Menlo, Courier, monospace;
220+
display: block;
221+
font-size: 14px;
222+
padding: 8px 16px;
223+
line-height: 1.5;
224+
border-radius: 5px;
225+
}
226+
227+
.hljs-comment {
228+
color: #608b4e;
229+
}
13230
</style>

0 commit comments

Comments
 (0)