Vue without the HTML
Vue is a beautiful technology, but it’s always felt a bit awkward crammed into old-school HTML. Louk is a tailor-made notation and preprocessor that hides the wonky stuff and lets Vue shine.
The key is that most things are interpreted as dynamic Vue entities (bound content and attributes) by default, while anything else is escaped with a single character. This means markup like {{ }}
and v-
becomes unnecessary, as it’s just assumed.
Louk runs on Node, and compiles into Vue HTML. Standalone Louk files can be compiled into full Vue components, or Louk notation can be embedded in Vue component sections.
The quickest way to get started with Louk is the louk-intro
template, which sets up a basic end-to-end development environment. If you’re integrating Louk into an existing project, download the libraries directly instead, and then configure louk-loader
:
npm install -D louk louk-loader
To get syntax highlighting, install the editor extension for Atom, Sublime, or VS Code.
All notation examples show Louk input followed by HTML output.
Elements are denoted by their tags as the first visible characters on a line. Nested elements are indented, and closing tags are implied. Self closing elements are followed with a forward slash.
h1
div
br/
<h1></h1>
<div><br /></div>
Element content follows the tag on the same line, separated by a space. Content is interpreted as dynamic by default.
div string
<div>{{string}}</div>
Directives and other attributes are denoted by prefixes and follow their corresponding elements on separate lines.
ul
:class focus
li
-for item in items
<ul v-bind:class="focus">
<li v-for="item in items"></li>
</ul>
Simple directives are denoted by a leading hyphen.
-if
becomes v-if
-for
becomes v-for
-model
becomes v-model
Binding directives are denoted by a leading colon.
:id
becomes v-bind:id
:class
becomes v-bind:class
:href
becomes v-bind:href
Action directives are denoted by a leading at sign.
@click
becomes v-on:click
@submit
becomes v-on:submit
@keyup.enter
becomes v-on:keyup.enter
Content can be made static by escaping the tag with a trailing double quote mark.
p" Hello world!
becomes <p>Hello world!</p>
Attributes can be made static by escaping the attribute name with a leading single quote mark.
'type text/css
becomes type="text/css"
Additionally, the class
, id
, and href
attributes can be made static by escaping the attribute value with a leading period, pound sign, or closing angle bracket, respectively.
.center
becomes class="center"
#install
becomes id="install"
>https://example.org
becomes href="https://example.org"
Element content can extend to additional lines by beginning the additional lines with a vertical pipe and space, at the same indentation level as the element tag, after any directives or attributes.
div a
.xyz
| b
<div class="xyz">{{a}}{{b}}</div>
Elements can be nested inside multiline content.
div a
span b
| c
<div>{{a}} <span>{{b}}</span> {{c}}</div>
Multiline content can be made static by following the vertical pipe with a double quote mark (|"
).
Single file component sections are denoted with a trailing comma, and must be unindented. Only the template
section will have its contents parsed as Louk.
template,
<!-- Template goes here -->
script,
// Script goes here
style,
/* Style goes here */
<template>
<!-- Template goes here -->
</template>
<script>
// Script goes here
</script>
<style>
/* Style goes here */
</style>
Comments are indicated with two leading forward slashes and will not be included in the HTML output.
div save
//Triggers dialog
@click confirm
<div v-on:click="confirm">{{save}}</div>
Raw HTML will be passed through unmodified. Louk notation can be included on new lines between HTML tags.
<div>
<!-- A comment -->
h1 title
#title
</div>
<div>
<!-- A comment -->
<h1 id="title">{{title}}</h1>
</div>
Indentation and newlines are kept by default, but can be removed with the whitespace
option.
louk(content, { whitespace: false });
Sections can be assigned default lang
attributes. Setting these explicitly in the component will override defaults.
louk(content, { langs: { style: "stylus" } });
template,
div
#main
button string
@click greet
script,
'lang ts
export default {
methods:{
greet: function(){alert('Hello!')}
},
data: function(){
return {string: 'Greet'}
}
}
style,
'scoped
button{
background-color: blue;
}
<template>
<div id="main"><button v-on:click="greet">{{string}}</button></div>
</template>
<script lang="ts">
export default {
methods: {
greet: function () {
alert("Hello!");
},
},
data: function () {
return { string: "Greet" };
},
};
</script>
<style scoped>
button {
background-color: blue;
}
</style>