Your vue SFC
is your document - Parsing Vue SFC
and generating documentation.
yarn global add vuese
-
Identify
name
,props
,events
,slots
,methods
and generate corresponding markdown content. -
Generate markdown files.
-
Document integration: generate a docute document.
-
Annotation enhancement (
@xxx
). -
cli
&Core module
for nodejs. -
Support
ts
& vue-class-component & vue-property-decorator -
Support for
slots
inrender
function. -
Identify
v-model
Previously: When you created a Vue component, you needed to manually write the documentation, including the components' props, events, slots, and some methods.
Now: If you created the following components.
<template>
<div>
<!-- Form header -->
<slot name="header">
<!-- `<th>title</th>` -->
<th>title</th>
</slot>
</div>
</template>
<script>
export default {
props: {
// The name of the form, up to 8 characters
name: {
type: [String, Number],
required: true,
validator () {}
}
},
methods: {
// @vuese
// Used to manually clear the form
clear () {
// Fire when the form is cleared
// @arg The argument is a boolean value representing xxx
this.$emit('onclear', true)
}
}
}
</script>
We assume that the above component is components/comp.vue
, then you only need to execute the following command:
vuese gen --include="components/*.vue"
Then you can choose which type of document to generate: just markdown or generate a docute document:
If you choose to generate a docute document, the document will be output in your command execution directory. At this point you can execute the following command:
vuese serve --open
It will launch a document server and automatically open the browser, as shown below:
vuese
will search vuese.config.js
or .vueserc
or vuese
property in package.json
from your base directory. The following options can be used both on the command line and in the configuration file.
- Type:
string
string[]
- Default:
["**/*.vue"]
Specify which .vue
files need to be generated, and by default include all .vue
files in the current directory and subdirectories.
- Type:
string
string[]
- Default:
[]
Specify which .vue
files do not need to be documented. Note: node_modules/**/*.vue
is excluded by default.
- Type:
string
- Default:
website
Output directory of the docute document.
- Type:
string
- Default:
components
The output directory of the markdown file, note: markdownDir
is based on outdir
, which means that the markdown file will be output to the website/components
directory.
- Type:
string
- Default:
''
Select the target to generate, can be either 'docute'
or 'markdown'
, if you don't specify genType
, vuese will ask you π.
- Type:
string
- Default:
''
If you want to generate a docute
document, you need to specify the sidbar title, if you don't specify title
, vuese will ask you too π.
vuese
exposes two modules: parser
and Render
.
The parser
function receives the contents of the .vue source file as the first argument, parses the string and gets the parsed result:
const { parser } = require('vuese')
// Read .vue source files
fs.readFile(abs, 'utf-8')
.then(source => {
const parserRes = parser(source)
})
interface ParserResult {
props?: PropsResult[]
events?: EventResult[]
slots?: SlotResult[]
methods?: MethodResult[]
name?: string
}
You can pass the second argument as a parsing option:
interface ParserOptions {
onProp?: {
(propsRes?: PropsResult[]): any
}
onEvent?: {
(eventRes?: EventResult): any
}
onMethod?: {
(methodRes?: MethodResult): any
}
onSlot?: {
(slotRes?: SlotResult): any
}
onName?: {
(name: string): any
}
babelParserPlugins?: ParserPlugin[]
}
The default parsing option is:
const defaultOptions: ParserOptions = {
onName(name: string) {
res.name = name
},
onProp(propsRes?: PropsResult[]) {
if (propsRes) {
res.props = propsRes
}
},
onEvent(eventsRes?: EventResult) {
if (eventsRes) {
;(res.events || (res.events = [])).push(eventsRes)
}
},
onSlot(slotRes?: SlotResult) {
if (slotRes) {
;(res.slots || (res.slots = [])).push(slotRes)
}
},
onMethod(methodRes?: MethodResult) {
if (methodRes) {
;(res.methods || (res.methods = [])).push(methodRes)
}
},
babelParserPlugins: ['objectRestSpread', 'dynamicImport']
}
Render
is a class that creates a render instance that receives the parsing result as a parameter:
const r = new Render(parserRes)
const renderRes = r.render()
interface RenderResult {
props?: string
slots?: string
events?: string
methods?: string
}
The process of writing a document is to write a comment for your code.
Assume we have a prop called name
:
props: {
name: {
type: String
}
}
When there are no comments, the generated document is as follows:
Name | Description | Type | Required | Default |
---|---|---|---|---|
name | - | String |
false |
- |
We noticed that the prop named name
is not described, in this case, we only need to add leading comments to the name attribute:
props: {
// The name of the form
name: {
type: String
}
}
In this way, the description of the prop will be included in the document, as shown below:
Name | Description | Type | Required | Default |
---|---|---|---|---|
name | The name of the form | String |
false |
- |
In addition, we also notice that the type
of prop called name
is automatically obtained from the type
attribute, but sometimes we need to show the user a more explicit choice, then we only need to add leading comments to the type attribute, as shown below:
props: {
// The name of the form
name: {
// `'TOP'` / `'BOTTOM'`
type: String
}
}
The generated document is as follows:
Name | Description | Type | Required | Default |
---|---|---|---|---|
name | The name of the form | 'TOP' / 'BOTTOM' |
false |
- |
Similarly, we can specify default values:
props: {
// The name of the form
name: {
// `'TOP'` / `'BOTTOM'`
type: String,
required: true,
default: 'TOP'
}
}
Then we get:
Name | Description | Type | Required | Default |
---|---|---|---|---|
name | The name of the form | 'TOP' / 'BOTTOM' |
true |
'TOP' |
Note: You can also add leading comments to the default
attribute.
Assume we have the following template which contains a named slot and default slot content:
<slot name="header">
<th>title</th>
</slot>
The generated document is as follows:
Name | Description | Default Slot Content |
---|---|---|
header | - | - |
We can see that the slot called header
is not described, and there is no description of the default slot content.
Then we add a comment to it:
<!-- Form header -->
<slot name="header">
<!-- `<th>title</th>` -->
<th>title</th>
</slot>
Then we get:
Name | Description | Default Slot Content |
---|---|---|
header | Form header | <th>title</th> |
Sometimes we will encounter nested slots:
<!-- Form header -->
<slot name="header">
<!-- `<th>title</th>` -->
<slot name="defaultHeader"></slot>
</slot>
Note: At this point, the comment content <!-- `<th>title</th>` -->
is not a description of the slot called defaultHeader
. It is still a description of the default slot contents of the slot called header
.
In order to add a description to the slot called defaultHeader
, we need to add another comment:
<!-- Form header -->
<slot name="header">
<!-- `<th>title</th>` -->
<!-- Custom form header -->
<slot name="defaultHeader"></slot>
</slot>
Then we get:
Name | Description | Default Slot Content |
---|---|---|
header | Form header | <th>title</th> |
defaultHeader | Custom form header | - |
Note: Vuese only treats this.$emit()
as an event
Assume we have the following code:
methods: {
clear () {
this.$emit('onclear')
}
}
The generated document is as follows:
Event Name | Description | Parameters |
---|---|---|
onclear | - | - |
Just add leading comments to it:
methods: {
clear () {
// Fire when the form is cleared
this.$emit('onclear', true)
}
}
Then we get:
Event Name | Description | Parameters |
---|---|---|
onclear | Fire when the form is cleared | - |
If you want to describe the parameters further, you need to use the @arg
identifier:
methods: {
clear () {
// Fire when the form is cleared
// @arg The argument is a boolean value representing xxx
this.$emit('onclear', true)
}
}
Then we get:
Event Name | Description | Parameters |
---|---|---|
onclear | Fire when the form is cleared | The argument is a boolean value representing xxx |
Similar to events, but with one difference, since not all methods need to be exposed to the developer, you need to use the @vuese
flag to tell vuese which methods are needed to generate the document:
methods: {
/**
* @vuese
* Used to manually clear the form
* @arg The argument is a boolean value representing xxx
*/
clear (bol) {
// ...
}
}
Then we get:
Method | Description | Parameters |
---|---|---|
clear | Used to manually clear the form | The argument is a boolean value representing xxx |
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
vuese Β© HcySunYang, Released under the MIT
54C4
License.
Authored and maintained by HcySunYang.
hcysun.me Β· GitHub @HcySunYang Β· Twitter @HcySunYang