Skip to content

feat: Vue components, mount options, global options, and v3 support #1409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
35ad5c5
Add vueOptions and vueGlobalOptions
jhildenbiddle Oct 10, 2020
cd8f2d3
Fix vueGlobalOptions.data checks
jhildenbiddle Oct 10, 2020
ecd053b
Support functions in docsify configuration
jhildenbiddle Oct 15, 2020
5fa79eb
Fix Vue content detection and global options
jhildenbiddle Oct 15, 2020
a2386e5
Add vueComponents support
jhildenbiddle Oct 16, 2020
bc2e091
Ignore `el` property in Vue configs for Vue v2
jhildenbiddle Oct 16, 2020
1774ab8
Initial commit
jhildenbiddle Oct 17, 2020
6d152e2
Refactor regular expression usage
jhildenbiddle Oct 17, 2020
758538c
Add `<output>`. Refactor `<pre>` and `<code>`.
jhildenbiddle Oct 17, 2020
0193659
Update docs with new Vue features and usage
jhildenbiddle Oct 17, 2020
8a56f72
Fix directive detection
jhildenbiddle Oct 18, 2020
5a2dde1
Update docs
jhildenbiddle Oct 20, 2020
1a52e97
Update docs
jhildenbiddle Oct 21, 2020
86dae61
Rename `vueOptions` to `vueMountOptions`
jhildenbiddle Oct 21, 2020
2946c06
Update test
jhildenbiddle Oct 21, 2020
871e48f
Update default waitForSelector value
jhildenbiddle Oct 21, 2020
131aae5
Fix waitForText() timeout and reject messages
jhildenbiddle Oct 23, 2020
af7e713
Change default startPath for tests & manual start
jhildenbiddle Oct 23, 2020
25084f8
Update jest/docsify side-effect cleanup
jhildenbiddle Oct 23, 2020
6a5e84b
Update directive detection (data vs static)
jhildenbiddle Oct 23, 2020
febe7f8
Remove global event listeners beforeEach
jhildenbiddle Oct 25, 2020
b6d5407
Fix basePath
jhildenbiddle Oct 25, 2020
8362ed0
Remove unnecessary globals
jhildenbiddle Oct 26, 2020
f0a8d69
Fix basePath update when config is function
jhildenbiddle Oct 26, 2020
5ec2256
Fix basePath & update route URLs
jhildenbiddle Oct 26, 2020
a9be6f2
Merge branch 'develop' into feat/vue-options
jhildenbiddle Oct 26, 2020
3af1cfa
Add selector option to _logHTML
jhildenbiddle Oct 26, 2020
b33d750
Remove SRC_PATH global variable
jhildenbiddle Oct 26, 2020
cafdd62
Remove —runInBand flag from test script
jhildenbiddle Oct 26, 2020
d9e491a
Fix covepage test
jhildenbiddle Oct 26, 2020
a5a431f
Fix base element reset
jhildenbiddle Nov 7, 2020
4e5dae7
Squashed commit of the following:
jhildenbiddle Nov 11, 2020
eae3ad8
Remove markdownlint config
jhildenbiddle Nov 11, 2020
421ef1d
Update docs
jhildenbiddle Nov 11, 2020
52cce02
Delete unnecessary file
jhildenbiddle Nov 11, 2020
727ee8f
Rename `vueMountOptions` to `vueMounts`
jhildenbiddle Nov 11, 2020
69efae3
Fix typos
jhildenbiddle Nov 11, 2020
51451a4
Remove BLANK_URL global
jhildenbiddle Nov 11, 2020
a10fcbd
Update Vue-related descriptions
jhildenbiddle Nov 12, 2020
9a1935a
Add support for Vue shorthand directive syntax
jhildenbiddle Nov 15, 2020
43a73bb
Merge branch 'develop' into feat/vue-options
sy-records Nov 16, 2020
7cf1e7c
Update Vue-related descriptions and links
jhildenbiddle Nov 19, 2020
7878c60
Merge branch 'develop' into feat/vue-options
jhildenbiddle Nov 19, 2020
90b67e2
Merge branch 'develop' into feat/vue-options
sy-records Nov 23, 2020
ffa7c90
Fix Lint
sy-records Nov 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update Vue-related descriptions
  • Loading branch information
jhildenbiddle committed Nov 12, 2020
commit a10fcbd9a613320e92d7393cf5024c15b9fd680c
6 changes: 3 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ window.$docsify = {

- type: `Object`

Registers Vue components using the component name as the key with an object containing Vue options as the value. Component data is not shared and changes will not persist as users navigate the site.
Registers Vue components using the component name as the key with an object containing Vue options as the value. Component `data` is unique for each instance and will not persist as users navigate the site.

```js
window.$docsify = {
Expand Down Expand Up @@ -667,7 +667,7 @@ window.$docsify = {

- type: `Object`

Specifies Vue options to be shared throughout your site. These options will be used when Docsify detects Vue content in the main content area that has not been previously mounted via [vueMounts](#vuemounts), [vueComponents](#vuecomponents), or a markdown `<script>`.
Specifies options for use with Vue content not explicitly mounted with [vueMounts](#mounting-dom-elements), [vueComponents](#components), or a [markdown script](#markdown-script). Changes to global `data` will persist and be reflected anywhere global references are used.

```js
window.$docsify = {
Expand Down Expand Up @@ -701,7 +701,7 @@ window.$docsify = {

- type: `Object`

Specifies DOM elements to mount as Vue instances and their associated options. Mount elements are specified using a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) as the key with an object containing Vue options as their value. Docsify will mount the first matching element in the main content area each time a new page is loaded.
Specifies DOM elements to mount as Vue instances and their associated options. Mount elements are specified using a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) as the key with an object containing Vue options as their value. Docsify will mount the first matching element in the main content area each time a new page is loaded. Mount element `data` is unique for each instance and will not persist as users navigate the site.

```js
window.$docsify = {
Expand Down
21 changes: 11 additions & 10 deletions docs/vue.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Vue [template syntax](https://vuejs.org/v2/guide/syntax.html) is used to create

[View output on GitHub](https://github.com/docsifyjs/docsify/blob/develop/docs/vue.md#template-syntax)

Vue content becomes more interesting when [data](#data), [computed properties](#computed-properties), [methods](#methods), and [lifecycle hooks](#lifecycle-hooks) are used. These options can be specified as [global options](#global-options) or, when [mounting DOM elements](#mounting-dom-elements), or within Vue [components](#components).
Vue content becomes more interesting when [data](#data), [computed properties](#computed-properties), [methods](#methods), and [lifecycle hooks](#lifecycle-hooks) are used. These options can be specified as [global options](#global-options) or within DOM [mounts](#mounts) and [components](#components).

### Data

Expand Down Expand Up @@ -189,7 +189,7 @@ Good {{ timeOfDay }}!

## Global options

Use `vueGlobalOptions` to share Vue options throughout your site. These options will be used when Docsify detects Vue content in the main content area that has not already been mounted with [vueMounts](#mounting-dom-elements), [vueComponents](#components), or a [markdown script](#markdown-script).
Use `vueGlobalOptions` to specify options for use with Vue content not explicitly mounted with [vueMounts](#mounts), [vueComponents](#components), or a [markdown script](#markdown-script). Changes to global `data` will persist and be reflected anywhere global references are used.

```js
window.$docsify = {
Expand Down Expand Up @@ -231,9 +231,9 @@ Notice the behavior when multiple global counters are rendered:

Changes made to one counter affect the both counters. This is because both instances reference the same global `count` value. Now, navigate to a new page and return to this section to see how changes made to global data persist between page loads.

## Mounting DOM elements
## Mounts

Use `vueMounts` to specify DOM elements to mount as Vue instances and their associated options. Mount elements are specified using a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) as the key with an object containing Vue options as their value. Docsify will mount the first matching element in the main content area each time a new page is loaded.
Use `vueMounts` to specify DOM elements to mount as Vue instances and their associated options. Mount elements are specified using a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) as the key with an object containing Vue options as their value. Docsify will mount the first matching element in the main content area each time a new page is loaded. Mount element `data` is unique for each instance and will not persist as users navigate the site.

```js
window.$docsify = {
Expand Down Expand Up @@ -265,7 +265,7 @@ window.$docsify = {

## Components

Use `vueComponents` to register Vue components using the component name as the key with an object containing Vue options as the value. Component data is not shared and changes will not persist as users navigate the site.
Use `vueComponents` to register Vue components using the component name as the key with an object containing Vue options as the value. Component `data` is unique for each instance and will not persist as users navigate the site.

```js
window.$docsify = {
Expand Down Expand Up @@ -324,10 +324,11 @@ Vue content can mounted using a `<script>` tag in your markdown pages.
## Technical Notes

- Docsify processes Vue content in the following order:
1. Markdown `<script>`
1. `vueMounts`
1. `vueGlobalOptions`
1. Execute markdown `<script>`
1. Register `vueComponents`
1. Mount DOM elements via `vueMounts`
1. Process unmounted Vue content using `vueGlobalOptions`
- Docsify will not mount an existing Vue instance or an element that contains an existing Vue instance.
- Docsify will automatically destroy/unmount all Vue instances it creates before new page content is loaded.
- When processing `vueGlobalOptions`, docsify parses each root element of the main content area and mounts the element if Vue content is detected. Docsify does not parse each individual node within the main content area.
- When processing `vueGlobalOptions`, docsify will only detect the full `v-` attribute syntax (e.g `v-bind:href` or `v-on:click`). For performance reasons, detection of Vue's [shorthand](https://vuejs.org/v2/guide/syntax.html#Shorthands) attribute syntax (e.g. `:href`or `@click`) is not supported.
- When processing `vueGlobalOptions`, docsify parses the child elements within the main content area (`#main`) and mounts the element if it contains Vue content. Docsify does not parse each individual node within the main content area.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not clear on the last bullet point. I guess if it'll start to explain this magic part, it might just need to go into more detail.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree this description could use some work. To be honest, I debated about even adding it. I've updated the description to (hopefully) make it more clear. At the end of the day, this text exists to help explain why this edge case won't work:

window.$docsify = {
  vueGlobalOptions: {
    data() {
      return {
        globalMsg: 'Hello from vueGlobalOptions!',
      };
    },
  },
  vueMounts: {
    '#test': {
      data() {
        return {
          mountMsg: 'Hello from vueMounts!'
        };
      },
    },
  },
};

Example 1: This will work

<!-- Source -->
<p>{{ globalMsg }}</p>
<p id="test">{{ mountMsg }}</p>
<!-- Output -->
<p>Hello from vueGlobalOptions!</p>
<p id="test">Hello from vueMounts!</p>

In this example, docsify first mounts the top-level <p id="test"> from vueMounts. Docsify then iterates over the top-level child elements (<p>), skips the ones that contain or are themselves Vue instances, detects Vue template syntax in the top-level <p> element, and mounts it using vueGlobalOptions. Great.

Example 2: This will not work

<!-- Source -->
<div>
  <p>{{ globalMsg }}</p>
  <p id="test">{{ mountMsg }}</p>
</div>
<!-- Output -->
<div>
  <p>{{ globalMsg }}</p>
  <p id="test">Hello from vueMounts!</p>
</div>

Like the previous example, docsify first mounts the top-level <p id="test"> from vueMounts. Docsify then iterates over the top-level child elements (<div>), detects that <div> contains a Vue instance (<p id="test">) and skips that element. This behavior is explained in the following "Technical Notes" bullet point:

  • Docsify will not mount an existing Vue instance or an element that contains an existing Vue instance.

I think it is highly unlikely that this will be an issue, but I added the related technical notes in hopes of making life easier for everyone if it does. The trick is how to do this succinctly without going into the same level of detail above. Hopefully the changes I've put in place are good enough for now. We can always revisit if/when needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jhildenbiddle The example of what works vs what doesn't will be very helpful to some people. I think it'd be worth pasting what you wrote into the docs.

- When processing `vueGlobalOptions`, docsify will only detect the full `v-` attribute syntax (e.g `v-bind:href` or `v-on:click`). For performance reasons, detection of Vue's [shorthand](https://vuejs.org/v2/guide/syntax.html#Shorthands) attribute syntax (e.g. `:href`or `@click`) is not supported. Shorthand syntax is supported when explicitly mounting Vue content via `vueComponents`, `vueMounts`, or a markdown `<script>`.