init at work
This commit is contained in:
Executable
+252
@@ -0,0 +1,252 @@
|
||||
# Templates, v-model, and Events
|
||||
|
||||
This note explains how Vue templates talk to your script code.
|
||||
|
||||
## Templates are HTML with Vue features
|
||||
|
||||
Example:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<p>{{ username }}</p>
|
||||
<input v-model="username" />
|
||||
<button @click="reset">Reset</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
const username = ref('mathias');
|
||||
|
||||
function reset() {
|
||||
username.value = '';
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
The same variable is:
|
||||
|
||||
- shown inside `{{ username }}`
|
||||
- edited by `<input v-model="username" />`
|
||||
- changed by the `reset()` function
|
||||
|
||||
## `{{ ... }}`: show a value
|
||||
|
||||
```vue
|
||||
<p>{{ username }}</p>
|
||||
<p>{{ isLoading ? 'Loading...' : 'Done' }}</p>
|
||||
<p>{{ 2 + 3 }}</p>
|
||||
```
|
||||
|
||||
This is interpolation. It prints a value into the rendered HTML.
|
||||
|
||||
## `v-model`: two-way binding
|
||||
|
||||
`v-model` connects a form field and a reactive variable.
|
||||
|
||||
```vue
|
||||
<input v-model="email" />
|
||||
```
|
||||
|
||||
```ts
|
||||
const email = ref('');
|
||||
```
|
||||
|
||||
Two-way binding means:
|
||||
|
||||
- if the user types, `email` changes
|
||||
- if code changes `email`, the input display changes
|
||||
|
||||
## Example with a select
|
||||
|
||||
```vue
|
||||
<v-select
|
||||
v-model="selectedCountry"
|
||||
:items="countries"
|
||||
label="Country"
|
||||
/>
|
||||
```
|
||||
|
||||
```ts
|
||||
const countries = ['Germany', 'France', 'Spain'];
|
||||
const selectedCountry = ref<string | null>(null);
|
||||
```
|
||||
|
||||
When the user picks France, `selectedCountry.value` becomes `'France'`.
|
||||
|
||||
## Your real example
|
||||
|
||||
From FlexibilityTable:
|
||||
|
||||
```vue
|
||||
<v-select
|
||||
v-model="selectedPeriodStartFrom"
|
||||
:items="periodStartOptions"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
label="Period start from"
|
||||
/>
|
||||
```
|
||||
|
||||
This means:
|
||||
|
||||
- the dropdown shows options from `periodStartOptions`
|
||||
- each option is an object
|
||||
- `title` is shown to the user
|
||||
- `value` is stored in `selectedPeriodStartFrom`
|
||||
|
||||
If one item is:
|
||||
|
||||
```ts
|
||||
{ title: '2026-03-23', value: '2026-03-23T23:00:00.000Z' }
|
||||
```
|
||||
|
||||
then the user sees:
|
||||
|
||||
```text
|
||||
2026-03-23
|
||||
```
|
||||
|
||||
but the stored value becomes:
|
||||
|
||||
```ts
|
||||
selectedPeriodStartFrom.value = '2026-03-23T23:00:00.000Z';
|
||||
```
|
||||
|
||||
## Events with `@click`
|
||||
|
||||
`@click` means: call a function when the element is clicked.
|
||||
|
||||
```vue
|
||||
<button @click="increment">Add</button>
|
||||
```
|
||||
|
||||
```ts
|
||||
function increment() {
|
||||
count.value += 1;
|
||||
}
|
||||
```
|
||||
|
||||
Other common events:
|
||||
|
||||
```vue
|
||||
<input @input="onInput" />
|
||||
<form @submit.prevent="submitForm" />
|
||||
<select @change="onChange" />
|
||||
```
|
||||
|
||||
## Binding attributes with `:`
|
||||
|
||||
The `:` shorthand means "bind this HTML or component prop to JavaScript".
|
||||
|
||||
```vue
|
||||
<button :disabled="isLoading">Save</button>
|
||||
```
|
||||
|
||||
Equivalent long form:
|
||||
|
||||
```vue
|
||||
<button v-bind:disabled="isLoading">Save</button>
|
||||
```
|
||||
|
||||
If `isLoading` is true, the button becomes disabled.
|
||||
|
||||
## Example: disable refresh button
|
||||
|
||||
In your component:
|
||||
|
||||
```vue
|
||||
<v-btn
|
||||
:disabled="loading || !hasValidPeriodRange"
|
||||
@click="applyDateFilters"
|
||||
>
|
||||
Refresh
|
||||
</v-btn>
|
||||
```
|
||||
|
||||
This means:
|
||||
|
||||
- disable the button if data is loading
|
||||
- also disable it if the selected date range is invalid
|
||||
- when clicked, run `applyDateFilters`
|
||||
|
||||
## Conditional rendering
|
||||
|
||||
Show something only if a condition is true:
|
||||
|
||||
```vue
|
||||
<p v-if="errorMessage">{{ errorMessage }}</p>
|
||||
<p v-else>No errors</p>
|
||||
```
|
||||
|
||||
## Loops with `v-for`
|
||||
|
||||
```vue
|
||||
<li v-for="user in users" :key="user.id">
|
||||
{{ user.name }}
|
||||
</li>
|
||||
```
|
||||
|
||||
This repeats the element for each item.
|
||||
|
||||
## Common beginner confusion: where does a template variable come from?
|
||||
|
||||
If you see this in a template:
|
||||
|
||||
```vue
|
||||
<p>{{ total }}</p>
|
||||
```
|
||||
|
||||
search the script for:
|
||||
|
||||
- `const total = ...`
|
||||
- `let total = ...`
|
||||
- `function total() ...`
|
||||
- `computed(() => ...)`
|
||||
- `defineProps(...)`
|
||||
|
||||
The template only knows values exposed by the script.
|
||||
|
||||
## Mental model for reading templates
|
||||
|
||||
For every template line, ask:
|
||||
|
||||
1. Is it displaying a value?
|
||||
2. Is it binding a prop?
|
||||
3. Is it listening for an event?
|
||||
4. Which script variable or function does it connect to?
|
||||
|
||||
## Mini Example: search box
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<input v-model="searchText" placeholder="Search users" />
|
||||
<button :disabled="!searchText" @click="search">Search</button>
|
||||
<p>You entered: {{ searchText }}</p>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
const searchText = ref('');
|
||||
|
||||
function search() {
|
||||
console.log('Searching for', searchText.value);
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Flow:
|
||||
|
||||
- user types into input
|
||||
- `searchText` updates
|
||||
- paragraph updates immediately
|
||||
- button disable state updates immediately
|
||||
- clicking Search uses current `searchText`
|
||||
|
||||
## Related Notes
|
||||
|
||||
- [[00-Vue for Python Developers]]
|
||||
- [[01-Refs, Computed, and Reactivity]]
|
||||
- [[03-Components, Props, Lifecycle, and Composables]]
|
||||
- [[04-FlexibilityTable Filter Flow]]
|
||||
Reference in New Issue
Block a user