Lançado · em melhoria
Guia de Vue.js · Nuxt · 3/6
Por enquanto, este capítulo está disponível apenas em inglês.
This chapter covers the ideas you need to read and write Vue code: single-file components, the reactivity APIs, template directives, props and emits, and Nuxt's file-based routing and auto-imports.
A .vue file is made of three blocks: <script setup>, <template> and <style>. <script setup> is the concise syntax for the Composition API; every variable, function and imported component declared inside it is available in the template. Adding scoped to the style block limits those styles to the current component.
ref wraps any value in a reactive container that you read and write through .value in script code (templates unwrap it for you). reactive makes an object itself reactive. computed caches a value derived from other state, and watch runs side effects when a value changes.
<script setup lang="ts">
import { ref, reactive, computed, watch } from "vue";
const query = ref("");
const filter = reactive({ onlyDone: false });
const todos = ref([
{ id: 1, text: "Learn Vue", done: true },
{ id: 2, text: "Try Nuxt", done: false },
]);
const visible = computed(() =>
todos.value
.filter((t) => !filter.onlyDone || t.done)
.filter((t) => t.text.includes(query.value)),
);
watch(query, (next, prev) => {
console.log(`query: ${prev} -> ${next}`);
});
</script>
<template>
<input v-model="query" placeholder="Search" />
<label><input type="checkbox" v-model="filter.onlyDone" /> Done only</label>
<ul>
<li v-for="todo in visible" :key="todo.id">{{ todo.text }}</li>
</ul>
<p v-if="visible.length === 0">No results.</p>
</template>Keep computed pure. Anything that touches the outside world, such as API calls or logging, belongs in watch or watchEffect.
| Directive | Shorthand | What it does |
|---|---|---|
v-bind:href | :href | Binds a value to an attribute |
v-on:click | @click | Handles an event |
v-model | Two-way binding between an input and state | |
v-if / v-else | Conditional rendering | |
v-show | Toggles visibility with CSS only |
v-for | Renders a list; always provide :key |
Parents pass data down through props, and children report changes up through events (emits). With TypeScript, you type defineProps and defineEmits directly.
<!-- components/TodoItem.vue -->
<script setup lang="ts">
const props = defineProps<{ text: string; done?: boolean }>();
const emit = defineEmits<{ toggle: []; remove: [reason: string] }>();
</script>
<template>
<li :class="{ done: props.done }">
<input type="checkbox" :checked="props.done" @change="emit('toggle')" />
{{ props.text }}
<button @click="emit('remove', 'user')">Remove</button>
</li>
</template>A parent uses it as <TodoItem :text="todo.text" :done="todo.done" @toggle="todo.done = !todo.done" />. Props are read-only, so a child asks for changes by emitting events instead of mutating them. When you need two-way binding, defineModel() connects directly to the parent's v-model. To let a parent inject content, render a <slot />.
In Nuxt, the path of a file in pages/ becomes its URL. Square brackets mark dynamic parameters.
pages/index.vue -> /
pages/about.vue -> /about
pages/posts/[id].vue -> /posts/:id<!-- pages/posts/[id].vue -->
<script setup lang="ts">
const route = useRoute();
definePageMeta({ layout: "default" });
</script>
<template>
<h1>Post {{ route.params.id }}</h1>
<NuxtLink to="/">Back to list</NuxtLink>
</template>Placing <NuxtPage /> in app.vue renders the page that matches the current URL, and <NuxtLink> navigates without a full page load.
Notice that the example above has no import statements. Nuxt automatically imports Vue APIs such as ref and computed, Nuxt composables such as useRoute and useFetch, components from components/, and functions from composables/ and utils/. A file at components/base/Button.vue is prefixed by its folder and becomes <BaseButton>. If you prefer explicit imports, you can still write import { ref } from "#imports".
<script setup> is usable in the template.ref through .value and reactive as a plain object; put derived values in computed and side effects in watch.pages/ and auto-imports APIs, components and composables.
0 comentários
Fazer login · Faça login para deixar um comentário.
Seja o primeiro a comentar.