Documenting Vue components

Hi! We're looking into documenting our Vue components in a user-friendly way, so that other developers can understand quickly how to use them, the props involved, etc. I took a look at JSDoc, and gave it a try. I added this block to the beginning of the <script> tag in my single-file component:

/**
* Creates a checkbox/radio button whose checked and unchecked states are icons entirely.
* @param {Boolean} [value=null] - Contains the v-model prop, and thus the variable bound, passed to this component.
* @param {String} [name] - The name HTML attribute of the form control. Should probably be the variable name of the value.
* @param {String} [iconUnchecked='icon-pin-outline'] - Class name of the icon for the unchecked state.
* @param {String} [iconChecked='icon-pin'] - Class name of the icon for the checked state.
* @param {Boolean} [stackIcons=true] - If true, the checked and unchecked icons will stack instead when checked. If false, only one icon will appear at a time.
* @param {String} [tagName='input'] - Name of the HTML element of the actual input. You probably don't want to change this.
* @param {String} [type='checkbox'] - The type HTML attribute of the form control. You can change this to "radio".
* @fires change - Hook onto the change event of this component to send API requests.
*/

But this doesn't seem to be working very well. It shows up in JS imports, although not 100% faithfully since it considers my thing a function:

In HTML templates, though, which is the main place I'd want the doc to show up, it's not showing up at all... although it does seem to understand that the "name" attribute is required.

Is there a better way to do this? A way that'd allow the doc to show up when people are inserting the component in the HTML template?

 

0
6 comments

Using JSDoc is the right way to document things, but it should normally be attached to the code (i.e. placed right above the corresponding class/function/variable). What does your code in `<script>` section look like exactly? Please share a code snippet.

Note that `@param` annotation is normally use for documenting functions

0

Hi! Here is most of the component. I stripped the styles, because they're not relevant.

I'm aware "@param" is for functions, but I'm not sure what I should use with Vue component props.

<template>
<label class="icon-control">
<span class="icon-control-inner">
<component
:is="tagName"
ref="hiddenControl"
class="hidden-control"
:value="value"
:checked="checked"
:type="type"
:name="name"
@change="emitChange()"
@input="emitInput()" />
<span class="icon-main icon-main-unchecked">
<i
:class="iconUnchecked"
class="the-icon icon" />
</span>
<span class="icon-main icon-main-checked">
<i
:class="iconChecked"
class="the-icon icon" />
</span>
</span>
</label>
</template>

<script>
/**
* Creates a checkbox/radio button whose checked and unchecked states are icons entirely.
* @param {Boolean} [value=null] - Contains the v-model prop, and thus the variable bound, passed to this component.
* @param {String} [name] - The name HTML attribute of the form control. Should probably be the variable name of the value.
* @param {String} [iconUnchecked='icon-pin-outline'] - Class name of the icon for the unchecked state.
* @param {String} [iconChecked='icon-pin'] - Class name of the icon for the checked state.
* @param {Boolean} [stackIcons=true] - If true, the checked and unchecked icons will stack instead when checked. If false, only one icon will appear at a time.
* @param {String} [tagName='input'] - Name of the HTML element of the actual input. You probably don't want to change this.
* @param {String} [type='checkbox'] - The type HTML attribute of the form control. You can change this to "radio".
* @fires change {Boolean}
* @fires input {Boolean}
*/
export default {
name: "IconControl",
props: {
value: { type: Boolean, default: null },
iconUnchecked: { type: String, default: 'icon-pin-outline' },
iconChecked: { type: String, default: 'icon-pin' },
stackIcons: { type: Boolean, default: true },
tagName: { type: String, default: 'input' },
type: { type: String, default: 'checkbox' },
name: { type: String, required: true }
},
computed: {
checked() {
return (
'input' == this.tagName
&& ( 'checkbox' == this.type || 'radio' == this.type )
&& this.value
);
}
},
methods: {
emitChange() {
this.$emit( 'change', this.$refs.hiddenControl.checked );
},
emitInput() {
this.$emit( 'input', this.$refs.hiddenControl.checked );
}
}
};
</script>

<style lang="scss">
</style>

 

0

Hi! Thanks for your answer.

I redid my documentation according to the VueStyleguidist docs, like this:

<template>
<label class="icon-control">
<span class="icon-control-inner">
<component
:is="tagName"
ref="hiddenControl"
class="hidden-control"
:checked="value"
:type="type"
:name="name"
@change="handleChange" />
<span class="icon-main icon-main-unchecked">
<i
:class="iconUnchecked"
class="the-icon icon" />
</span>
<span class="icon-main icon-main-checked">
<i
:class="iconChecked"
class="the-icon icon" />
</span>
</span>
</label>
</template>

<script>
/**
* Creates a checkbox/radio button whose checked and unchecked states are icons entirely.
* @displayName IconControl
*/
export default {
name: "IconControl",
model: {
event: 'change'
},
props: {
/**
* Contains the v-model prop, and thus the variable bound, passed to this component.
* @model
*/
value: { type: Boolean, default: false },
/**
* Name of the HTML element of the actual input. You probably don't want to change this.
*/
tagName: { type: String, default: 'input' },
/**
* Class name of the icon for the unchecked state.
*/
iconUnchecked: { type: String, default: 'icon-pin-outline' },
/**
* Class name of the icon for the checked state.
*/
iconChecked: { type: String, default: 'icon-pin' },
/**
* If true, the checked and unchecked icons will stack instead when checked. If false, only one icon will appear at a time.
*/
stackIcons: { type: Boolean, default: true },
/**
* The type HTML attribute of the form control. You can change this to "radio".
* @values checkbox, radio
*/
type: { type: String, default: 'checkbox' },
/**
* The name HTML attribute of the form control. Should probably be the variable name of the value.
*/
name: { type: String, required: true }
},
watch: {
// The parent changed the value. Let's make sure the checkbox's state matches.
value( newVal ) {
this.$refs.hiddenControl.checked = newVal
}
},
methods: {
// Checkbox was manually checked. Let's alert the parent. Value is not changed yet at this point. It's the parent's job to update it.
handleChange() {
/**
* Checkbox was toggled. (Fires before change)
* @property {boolean} newVal - Whether the input is now checked.
*/
this.$emit( 'input', this.$refs.hiddenControl.checked )
/**
* Checkbox was toggled. (Fires after input)
* @property {boolean} newVal - Whether the input is now checked.
*/
this.$emit( 'change', this.$refs.hiddenControl.checked )
}
}
};
</script>

<style lang="scss">
</style>

(Also the component changed a little in the mean time; please don't mind that.)

Now WebStorm recognizes my documentation even less though.

In JS:

In HTML:

 

Is there a way to make WebStorm recognize Vue-Styleguidist doc comments?

0

Showing documentation for custom Vue components is not yet supported, please follow https://youtrack.jetbrains.com/issue/WEB-42015 for updates

2

I see! Thanks. I'm looking forward to this feature. :)

1

Please sign in to leave a comment.