docsify/docs/vue.md
John Hildenbiddle 5a2dde1624 Update docs
2020-10-20 17:45:34 -05:00

8.5 KiB

Vue compatibility

Docsify allows Vue content to be added directly to you markdown pages. This can greatly simplify working with data and adding reactivity to your site.

To get started, add either Vue 2.x or 3.x to your index.html file:

<!-- Vue 2.x (production)-->
<script src="//cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js"></script>

<!-- Vue 3.x (production) -->
<script src="//cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>

The URLs above will load a production version of Vue which has been optimized for performance. Alternatively, development versions of Vue are available that are larger in size but offer helpful console warnings and Vue.js devtools support:

<!-- Vue 2.x (development) -->
<script src="//cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

<!-- Vue 3.x (development) -->
<script src="//cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>

Template syntax

Vue template syntax is used to create dynamic content. With no additinal configuration, this syntax offers several useful features like support for JavaScript expressions and Vue directives for loops and conditional rendering.

<!-- Hide in docsify, show elsewhere (e.g. GitHub) -->
<p v-if="false">Text for GitHub</p>

<!-- Sequenced content (i.e. loop)-->
<ul>
  <li v-for="i in 3">Item {{ i }}</li>
</ul>

<!-- JavaScript expressions -->
<p>2 + 2 = {{ 2 + 2 }}</p>

Text for GitHub

  • Item {{ i }}

2 + 2 = {{ 2 + 2 }}

View output on GitHub

Vue content becomes more interesting when data, computed properties, methods, and lifecycle hooks are used. These options can be specified as global options, instance options, or within components.

Data

{
  data() {
    return {
      message: 'Hello, World!'
    };
  }
}
<!-- Show message in docsify, show "{{ message }}" elsewhere (e.g. GitHub)  -->
{{ message }}

<!-- Show message in docsify, hide elsewhere (e.g. GitHub)  -->
<p v-text="message"></p>

<!-- Show message in docsify, show text elsewhere (e.g. GitHub)  -->
<p v-text="message">Text for GitHub</p>

{{ message }}

Text for GitHub

View output on GitHub

Computed properties

{
  computed: {
    timeOfDay() {
      const date = new Date();
      const hours = date.getHours();

      if (hours < 12) {
        return 'morning';
      }
      else if (hours < 18) {
        return 'afternoon';
      }
      else {
        return 'evening'
      }
    }
  },
}
Good {{ timeOfDay }}!

Good {{ timeOfDay }}!

Methods

{
  data() {
    return {
      message: 'Hello, World!'
    };
  },
  methods: {
    hello() {
      alert(this.message);
    }
  },
}

Say Hello

Lifecycle Hooks

{
  data() {
    return {
      images: null,
    };
  },
  created() {
    fetch('https://api.domain.com/')
      .then(response => response.json())
      .then(data => (this.images = data))
      .catch(err => console.log(err));
  }
}

// API response:
// [
//   { title: 'Image 1', url: 'https://domain.com/1.jpg' },
//   { title: 'Image 2', url: 'https://domain.com/2.jpg' },
//   { title: 'Image 3', url: 'https://domain.com/3.jpg' },
// ];
<div style="display: flex;">
  <figure style="flex: 1;">
    <img v-for="image in images" :src="image.url" :title="image.title">
    <figcaption>{{ image.title }}</figcaption>
  </figure>
</div>
{{ image.title }}

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 been previously mounted via instance options, components, or a markdown script. Global data() is shared and changes will persist as users navigate the site.

window.$docsify = {
  vueGlobalOptions: {
    data() {
      return {
        count: 0,
      };
    },
  },
};
<p>
  <button v-on:click="count -= 1">-</button>
  {{ count }}
  <button v-on:click="count += 1">+</button>
</p>

Notice the behavior when multilpe global counters are rendered below: changes made to one counter affect the other because both instances reference the global count value.

- {{ count }} +

- {{ count }} +

Now, navigate to a new page and return to this section to see how changes made to global data persist.

Instance options

Use vueOptions to specify Vue mount elements and their associated options. Mount elements are specified using a CSS selector as the key with an object containing Vue options as their value. Docsify will mount the first matching element in the main content area (#main, .markdown-section) each time a new page is loaded. Instance data is not shared and changes will not persist as users navigate the site.

window.$docsify = {
  vueOptions: {
    '#counter': {
      data() {
        return {
          count: 0,
        };
      },
    },
  },
};
<div id="counter">
  <button v-on:click="count -= 1">-</button>
  {{ count }}
  <button v-on:click="count += 1">+</button>
</div>
- {{ count }} +

Components

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

window.$docsify = {
  vueComponents: {
    'button-counter': {
      template: `
        <button @click="count += 1">
          You clicked me {{ count }} times
        </button>
      `,
      data() {
        return {
          count: 0,
        };
      },
    },
  },
};
<button-counter></button-counter>
<button-counter></button-counter>

Markdown script

Vue content can mounted using a <script> tag in your markdown pages.

!> Only the first <script> tag in a markdown file is executed. If you are working with multiple Vue components, all Vue instances must be created within the first <script> tag in your markdown.

<!-- Vue 2.x  -->
<script>
  new Vue({
    el: '#example',
    // Options...
  });
</script>
<!-- Vue 3.x  -->
<script>
  Vue.createApp({
    // Options...
  }).mount('#example');
</script>

Technical Notes

  • Docsify processes Vue content in the following order:
    1. markdown script,
    2. vueOptions
    3. vueGlobalOptions
  • Docsify will not mount an element that is already a Vue instance or contains a Vue instance.
  • Docsify will automatically destroy/unmount all Vue instances it creates.
  • 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 detects the full v- attribute syntax (e.g v-bind:href or v-on:click) but not the shorthand syntax (e.g. :hrefor @click).