How about some interactivity inside a note?
...and here's the code that implements the above button:
<p>
<button @click="count++" :disabled="!mounted">0</button>
</p>
<script>
export default {
setup() {
const count = Vue.ref(0)
const mounted = Vue.ref(false)
Vue.onMounted(() => {
mounted.value = true
})
return { hello: 'Hello, World', count, mounted }
},
}
</script>
Here's how it works:
- The server-side code first converts Markdown to HTML using
@vuepress/markdown
. It automatically extracts out the<script>
and<style>
tags. - The HTML is then parsed as a Vue template and compiled into render functions using
vue-template-compiler
as JavaScript source code. - The
<script>
tag is compiled using esbuild into a JavaScript source code. - The resulting source codes are then used to assemble a Vue component. This happens both on the client and on the server. The server then renders a static HTML version of the component, and the client then hydrates it.
Archive — How it works in the previous version of notes.dt.in.th (Nuxt-based)
Here's how it works:
In the contents API, when the Markdown file is parsed,
@vuepress/markdown
automatically extracts out the<script>
and<style>
tags. I assume that there will be only one<script>
tag. If one is found, then the contents of the<script>
tag is compiled down to ES6 + CommonJS using esbuild. This compiled JavaScript is then returned over the wire.In the Nuxt app, if a component module is included in the response, Nuxt will compile that code as part of the Vue component, on-the-fly, at runtime.
This results in the following markup:
For full changes, see the pull request.