Skip to main content Svelte Highlight v7.21.1

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>