Vue language preview
1. Script setup with TypeScript
horizon-dark
<script setup lang="ts">
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
function increment() {
count.value += 1;
}
</script>
<template>
<button @click="increment">{{ doubled }}</button>
</template>atom-one-dark
<script setup lang="ts">
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
function increment() {
count.value += 1;
}
</script>
<template>
<button @click="increment">{{ doubled }}</button>
</template>github-dark
<script setup lang="ts">
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
function increment() {
count.value += 1;
}
</script>
<template>
<button @click="increment">{{ doubled }}</button>
</template>dracula
<script setup lang="ts">
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
function increment() {
count.value += 1;
}
</script>
<template>
<button @click="increment">{{ doubled }}</button>
</template>nord
<script setup lang="ts">
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
function increment() {
count.value += 1;
}
</script>
<template>
<button @click="increment">{{ doubled }}</button>
</template>github
<script setup lang="ts">
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
function increment() {
count.value += 1;
}
</script>
<template>
<button @click="increment">{{ doubled }}</button>
</template>2. Options API script block
horizon-dark
<script>
export default {
data() {
return { count: 0, name: "" };
},
methods: {
increment() {
this.count += 1;
},
},
};
</script>atom-one-dark
<script>
export default {
data() {
return { count: 0, name: "" };
},
methods: {
increment() {
this.count += 1;
},
},
};
</script>github-dark
<script>
export default {
data() {
return { count: 0, name: "" };
},
methods: {
increment() {
this.count += 1;
},
},
};
</script>dracula
<script>
export default {
data() {
return { count: 0, name: "" };
},
methods: {
increment() {
this.count += 1;
},
},
};
</script>nord
<script>
export default {
data() {
return { count: 0, name: "" };
},
methods: {
increment() {
this.count += 1;
},
},
};
</script>github
<script>
export default {
data() {
return { count: 0, name: "" };
},
methods: {
increment() {
this.count += 1;
},
},
};
</script>3. Template directives
horizon-dark
<template>
<div v-if="visible" :class="{ active: isActive }">
<input v-model="name" @keyup.enter="submit" />
<ul>
<li v-for="item in items" :key="item.id">{{ item.label }}</li>
</ul>
<template #header="{ title }">
<h1>{{ title }}</h1>
</template>
</div>
</template>atom-one-dark
<template>
<div v-if="visible" :class="{ active: isActive }">
<input v-model="name" @keyup.enter="submit" />
<ul>
<li v-for="item in items" :key="item.id">{{ item.label }}</li>
</ul>
<template #header="{ title }">
<h1>{{ title }}</h1>
</template>
</div>
</template>github-dark
<template>
<div v-if="visible" :class="{ active: isActive }">
<input v-model="name" @keyup.enter="submit" />
<ul>
<li v-for="item in items" :key="item.id">{{ item.label }}</li>
</ul>
<template #header="{ title }">
<h1>{{ title }}</h1>
</template>
</div>
</template>dracula
<template>
<div v-if="visible" :class="{ active: isActive }">
<input v-model="name" @keyup.enter="submit" />
<ul>
<li v-for="item in items" :key="item.id">{{ item.label }}</li>
</ul>
<template #header="{ title }">
<h1>{{ title }}</h1>
</template>
</div>
</template>nord
<template>
<div v-if="visible" :class="{ active: isActive }">
<input v-model="name" @keyup.enter="submit" />
<ul>
<li v-for="item in items" :key="item.id">{{ item.label }}</li>
</ul>
<template #header="{ title }">
<h1>{{ title }}</h1>
</template>
</div>
</template>github
<template>
<div v-if="visible" :class="{ active: isActive }">
<input v-model="name" @keyup.enter="submit" />
<ul>
<li v-for="item in items" :key="item.id">{{ item.label }}</li>
</ul>
<template #header="{ title }">
<h1>{{ title }}</h1>
</template>
</div>
</template>4. Longhand directive arguments
horizon-dark
<template>
<a v-bind:href="url" v-on:click.prevent="track">
<base-layout>
<template v-slot:header="{ title }">
<h1>{{ title }}</h1>
</template>
</base-layout>
</a>
</template>atom-one-dark
<template>
<a v-bind:href="url" v-on:click.prevent="track">
<base-layout>
<template v-slot:header="{ title }">
<h1>{{ title }}</h1>
</template>
</base-layout>
</a>
</template>github-dark
<template>
<a v-bind:href="url" v-on:click.prevent="track">
<base-layout>
<template v-slot:header="{ title }">
<h1>{{ title }}</h1>
</template>
</base-layout>
</a>
</template>dracula
<template>
<a v-bind:href="url" v-on:click.prevent="track">
<base-layout>
<template v-slot:header="{ title }">
<h1>{{ title }}</h1>
</template>
</base-layout>
</a>
</template>nord
<template>
<a v-bind:href="url" v-on:click.prevent="track">
<base-layout>
<template v-slot:header="{ title }">
<h1>{{ title }}</h1>
</template>
</base-layout>
</a>
</template>github
<template>
<a v-bind:href="url" v-on:click.prevent="track">
<base-layout>
<template v-slot:header="{ title }">
<h1>{{ title }}</h1>
</template>
</base-layout>
</a>
</template>5. Scoped SCSS styles
horizon-dark
<style scoped lang="scss">
$primary: #42b883;
.card {
color: $primary;
&:hover {
opacity: 0.9;
}
}
</style>atom-one-dark
<style scoped lang="scss">
$primary: #42b883;
.card {
color: $primary;
&:hover {
opacity: 0.9;
}
}
</style>github-dark
<style scoped lang="scss">
$primary: #42b883;
.card {
color: $primary;
&:hover {
opacity: 0.9;
}
}
</style>dracula
<style scoped lang="scss">
$primary: #42b883;
.card {
color: $primary;
&:hover {
opacity: 0.9;
}
}
</style>nord
<style scoped lang="scss">
$primary: #42b883;
.card {
color: $primary;
&:hover {
opacity: 0.9;
}
}
</style>github
<style scoped lang="scss">
$primary: #42b883;
.card {
color: $primary;
&:hover {
opacity: 0.9;
}
}
</style>6. Less and Stylus style blocks
horizon-dark
<style scoped lang="less">
@brand: #35495e;
.title {
color: @brand;
}
</style>
<style lang="stylus">
.card
padding 1rem
</style>atom-one-dark
<style scoped lang="less">
@brand: #35495e;
.title {
color: @brand;
}
</style>
<style lang="stylus">
.card
padding 1rem
</style>github-dark
<style scoped lang="less">
@brand: #35495e;
.title {
color: @brand;
}
</style>
<style lang="stylus">
.card
padding 1rem
</style>dracula
<style scoped lang="less">
@brand: #35495e;
.title {
color: @brand;
}
</style>
<style lang="stylus">
.card
padding 1rem
</style>nord
<style scoped lang="less">
@brand: #35495e;
.title {
color: @brand;
}
</style>
<style lang="stylus">
.card
padding 1rem
</style>github
<style scoped lang="less">
@brand: #35495e;
.title {
color: @brand;
}
</style>
<style lang="stylus">
.card
padding 1rem
</style>7. Custom directives
horizon-dark
<script setup>
import { vFocus, vTooltip } from "./directives";
</script>
<template>
<input v-focus placeholder="Autofocused" />
<button v-tooltip="'Click me'" v-permission.admin="'edit'">
Save
</button>
</template>atom-one-dark
<script setup>
import { vFocus, vTooltip } from "./directives";
</script>
<template>
<input v-focus placeholder="Autofocused" />
<button v-tooltip="'Click me'" v-permission.admin="'edit'">
Save
</button>
</template>github-dark
<script setup>
import { vFocus, vTooltip } from "./directives";
</script>
<template>
<input v-focus placeholder="Autofocused" />
<button v-tooltip="'Click me'" v-permission.admin="'edit'">
Save
</button>
</template>dracula
<script setup>
import { vFocus, vTooltip } from "./directives";
</script>
<template>
<input v-focus placeholder="Autofocused" />
<button v-tooltip="'Click me'" v-permission.admin="'edit'">
Save
</button>
</template>nord
<script setup>
import { vFocus, vTooltip } from "./directives";
</script>
<template>
<input v-focus placeholder="Autofocused" />
<button v-tooltip="'Click me'" v-permission.admin="'edit'">
Save
</button>
</template>github
<script setup>
import { vFocus, vTooltip } from "./directives";
</script>
<template>
<input v-focus placeholder="Autofocused" />
<button v-tooltip="'Click me'" v-permission.admin="'edit'">
Save
</button>
</template>Kitchen sink
horizon-dark
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
type Item = { id: number; label: string };
interface Props {
title: string;
items?: Item[];
}
const props = withDefaults(defineProps<Props>(), {
items: () => [],
});
const emit = defineEmits<{
submit: [value: string];
update: [count: number];
}>();
const count = ref(0);
const name = ref("");
const visible = ref(true);
const isActive = ref(false);
const doubled = computed(() => count.value * 2);
const greeting = computed(() => `Hello, ${name.value || "Anonymous"}!`);
watch(count, (value) => {
emit("update", value);
});
function increment() {
count.value += 1;
}
function submit() {
emit("submit", name.value);
}
onMounted(() => {
console.log("mounted", props.title);
});
</script>
<template>
<!-- Template directives and mustache expressions -->
<header v-if="visible">
<h1>{{ title }}</h1>
<p>{{ greeting }} · {{ doubled }} clicks</p>
</header>
<div
v-show="visible"
:class="{ active: isActive, card: true }"
:style="{ opacity: count / 10 }"
>
<input v-model="name" placeholder="Name" @keyup.enter="submit" />
<button @click="increment" @keydown.enter="increment">+1</button>
<button v-on:click="isActive = !isActive">Toggle</button>
</div>
<ul v-if="items.length">
<li v-for="item in items" :key="item.id" v-memo="[item.id]">
{{ item.label }}
</li>
</ul>
<p v-else>No items</p>
<Child v-slot="{ message }">
<span>{{ message }}</span>
</Child>
<template #footer>
<small>Built with Vue</small>
</template>
</template>
<style scoped lang="scss">
$brand: #42b883;
.card {
padding: 1rem;
border: 1px solid #ccc;
&.active {
border-color: $brand;
}
}
:deep(.nested) {
margin: 0;
}
</style>
<style scoped lang="less">
@muted: #666;
small {
color: @muted;
}
</style>atom-one-dark
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
type Item = { id: number; label: string };
interface Props {
title: string;
items?: Item[];
}
const props = withDefaults(defineProps<Props>(), {
items: () => [],
});
const emit = defineEmits<{
submit: [value: string];
update: [count: number];
}>();
const count = ref(0);
const name = ref("");
const visible = ref(true);
const isActive = ref(false);
const doubled = computed(() => count.value * 2);
const greeting = computed(() => `Hello, ${name.value || "Anonymous"}!`);
watch(count, (value) => {
emit("update", value);
});
function increment() {
count.value += 1;
}
function submit() {
emit("submit", name.value);
}
onMounted(() => {
console.log("mounted", props.title);
});
</script>
<template>
<!-- Template directives and mustache expressions -->
<header v-if="visible">
<h1>{{ title }}</h1>
<p>{{ greeting }} · {{ doubled }} clicks</p>
</header>
<div
v-show="visible"
:class="{ active: isActive, card: true }"
:style="{ opacity: count / 10 }"
>
<input v-model="name" placeholder="Name" @keyup.enter="submit" />
<button @click="increment" @keydown.enter="increment">+1</button>
<button v-on:click="isActive = !isActive">Toggle</button>
</div>
<ul v-if="items.length">
<li v-for="item in items" :key="item.id" v-memo="[item.id]">
{{ item.label }}
</li>
</ul>
<p v-else>No items</p>
<Child v-slot="{ message }">
<span>{{ message }}</span>
</Child>
<template #footer>
<small>Built with Vue</small>
</template>
</template>
<style scoped lang="scss">
$brand: #42b883;
.card {
padding: 1rem;
border: 1px solid #ccc;
&.active {
border-color: $brand;
}
}
:deep(.nested) {
margin: 0;
}
</style>
<style scoped lang="less">
@muted: #666;
small {
color: @muted;
}
</style>github-dark
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
type Item = { id: number; label: string };
interface Props {
title: string;
items?: Item[];
}
const props = withDefaults(defineProps<Props>(), {
items: () => [],
});
const emit = defineEmits<{
submit: [value: string];
update: [count: number];
}>();
const count = ref(0);
const name = ref("");
const visible = ref(true);
const isActive = ref(false);
const doubled = computed(() => count.value * 2);
const greeting = computed(() => `Hello, ${name.value || "Anonymous"}!`);
watch(count, (value) => {
emit("update", value);
});
function increment() {
count.value += 1;
}
function submit() {
emit("submit", name.value);
}
onMounted(() => {
console.log("mounted", props.title);
});
</script>
<template>
<!-- Template directives and mustache expressions -->
<header v-if="visible">
<h1>{{ title }}</h1>
<p>{{ greeting }} · {{ doubled }} clicks</p>
</header>
<div
v-show="visible"
:class="{ active: isActive, card: true }"
:style="{ opacity: count / 10 }"
>
<input v-model="name" placeholder="Name" @keyup.enter="submit" />
<button @click="increment" @keydown.enter="increment">+1</button>
<button v-on:click="isActive = !isActive">Toggle</button>
</div>
<ul v-if="items.length">
<li v-for="item in items" :key="item.id" v-memo="[item.id]">
{{ item.label }}
</li>
</ul>
<p v-else>No items</p>
<Child v-slot="{ message }">
<span>{{ message }}</span>
</Child>
<template #footer>
<small>Built with Vue</small>
</template>
</template>
<style scoped lang="scss">
$brand: #42b883;
.card {
padding: 1rem;
border: 1px solid #ccc;
&.active {
border-color: $brand;
}
}
:deep(.nested) {
margin: 0;
}
</style>
<style scoped lang="less">
@muted: #666;
small {
color: @muted;
}
</style>dracula
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
type Item = { id: number; label: string };
interface Props {
title: string;
items?: Item[];
}
const props = withDefaults(defineProps<Props>(), {
items: () => [],
});
const emit = defineEmits<{
submit: [value: string];
update: [count: number];
}>();
const count = ref(0);
const name = ref("");
const visible = ref(true);
const isActive = ref(false);
const doubled = computed(() => count.value * 2);
const greeting = computed(() => `Hello, ${name.value || "Anonymous"}!`);
watch(count, (value) => {
emit("update", value);
});
function increment() {
count.value += 1;
}
function submit() {
emit("submit", name.value);
}
onMounted(() => {
console.log("mounted", props.title);
});
</script>
<template>
<!-- Template directives and mustache expressions -->
<header v-if="visible">
<h1>{{ title }}</h1>
<p>{{ greeting }} · {{ doubled }} clicks</p>
</header>
<div
v-show="visible"
:class="{ active: isActive, card: true }"
:style="{ opacity: count / 10 }"
>
<input v-model="name" placeholder="Name" @keyup.enter="submit" />
<button @click="increment" @keydown.enter="increment">+1</button>
<button v-on:click="isActive = !isActive">Toggle</button>
</div>
<ul v-if="items.length">
<li v-for="item in items" :key="item.id" v-memo="[item.id]">
{{ item.label }}
</li>
</ul>
<p v-else>No items</p>
<Child v-slot="{ message }">
<span>{{ message }}</span>
</Child>
<template #footer>
<small>Built with Vue</small>
</template>
</template>
<style scoped lang="scss">
$brand: #42b883;
.card {
padding: 1rem;
border: 1px solid #ccc;
&.active {
border-color: $brand;
}
}
:deep(.nested) {
margin: 0;
}
</style>
<style scoped lang="less">
@muted: #666;
small {
color: @muted;
}
</style>nord
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
type Item = { id: number; label: string };
interface Props {
title: string;
items?: Item[];
}
const props = withDefaults(defineProps<Props>(), {
items: () => [],
});
const emit = defineEmits<{
submit: [value: string];
update: [count: number];
}>();
const count = ref(0);
const name = ref("");
const visible = ref(true);
const isActive = ref(false);
const doubled = computed(() => count.value * 2);
const greeting = computed(() => `Hello, ${name.value || "Anonymous"}!`);
watch(count, (value) => {
emit("update", value);
});
function increment() {
count.value += 1;
}
function submit() {
emit("submit", name.value);
}
onMounted(() => {
console.log("mounted", props.title);
});
</script>
<template>
<!-- Template directives and mustache expressions -->
<header v-if="visible">
<h1>{{ title }}</h1>
<p>{{ greeting }} · {{ doubled }} clicks</p>
</header>
<div
v-show="visible"
:class="{ active: isActive, card: true }"
:style="{ opacity: count / 10 }"
>
<input v-model="name" placeholder="Name" @keyup.enter="submit" />
<button @click="increment" @keydown.enter="increment">+1</button>
<button v-on:click="isActive = !isActive">Toggle</button>
</div>
<ul v-if="items.length">
<li v-for="item in items" :key="item.id" v-memo="[item.id]">
{{ item.label }}
</li>
</ul>
<p v-else>No items</p>
<Child v-slot="{ message }">
<span>{{ message }}</span>
</Child>
<template #footer>
<small>Built with Vue</small>
</template>
</template>
<style scoped lang="scss">
$brand: #42b883;
.card {
padding: 1rem;
border: 1px solid #ccc;
&.active {
border-color: $brand;
}
}
:deep(.nested) {
margin: 0;
}
</style>
<style scoped lang="less">
@muted: #666;
small {
color: @muted;
}
</style>github
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
type Item = { id: number; label: string };
interface Props {
title: string;
items?: Item[];
}
const props = withDefaults(defineProps<Props>(), {
items: () => [],
});
const emit = defineEmits<{
submit: [value: string];
update: [count: number];
}>();
const count = ref(0);
const name = ref("");
const visible = ref(true);
const isActive = ref(false);
const doubled = computed(() => count.value * 2);
const greeting = computed(() => `Hello, ${name.value || "Anonymous"}!`);
watch(count, (value) => {
emit("update", value);
});
function increment() {
count.value += 1;
}
function submit() {
emit("submit", name.value);
}
onMounted(() => {
console.log("mounted", props.title);
});
</script>
<template>
<!-- Template directives and mustache expressions -->
<header v-if="visible">
<h1>{{ title }}</h1>
<p>{{ greeting }} · {{ doubled }} clicks</p>
</header>
<div
v-show="visible"
:class="{ active: isActive, card: true }"
:style="{ opacity: count / 10 }"
>
<input v-model="name" placeholder="Name" @keyup.enter="submit" />
<button @click="increment" @keydown.enter="increment">+1</button>
<button v-on:click="isActive = !isActive">Toggle</button>
</div>
<ul v-if="items.length">
<li v-for="item in items" :key="item.id" v-memo="[item.id]">
{{ item.label }}
</li>
</ul>
<p v-else>No items</p>
<Child v-slot="{ message }">
<span>{{ message }}</span>
</Child>
<template #footer>
<small>Built with Vue</small>
</template>
</template>
<style scoped lang="scss">
$brand: #42b883;
.card {
padding: 1rem;
border: 1px solid #ccc;
&.active {
border-color: $brand;
}
}
:deep(.nested) {
margin: 0;
}
</style>
<style scoped lang="less">
@muted: #666;
small {
color: @muted;
}
</style>