Vue 3: Diferenzas entre revisións

De Wiki do Ciclo ASIR do IES de Rodeira
Saltar á navegación Saltar á procura
 
(Non se amosan 104 revisións do historial feitas polo mesmo usuario.)
Liña 1: Liña 1:
==Introdución==
==Introdución==
Vue (pronunciado /vjuː/, como view) é un framework progresivo para construír interfaces de usuario. A diferenza doutros frameworks monolíticos, Vue está deseñado dende cero para ser utilizado de maneira incremental. A biblioteca central está enfocada só na capa de visualización, e é doada de utilizar e integrar con outras bibliotecas ou proxectos existentes.
Vue (pronunciado /vjuː/, como view) é un framework progresivo para construír interfaces de usuario. A biblioteca central está enfocada só na capa de visualización, e é doada de utilizar e integrar con outras bibliotecas ou proxectos existentes.


Vue dispón dun "compilador" que se encarga de transformar as plantillas de Vue en código JavaScript optimizado que utilizará o navegador para renderizar o contido. Se encarga de convertir as directrices e etiquetas Vue (como v-if, v-for) en funcións JavaScript que manipulan o DOM.
Vue dispón dun "compilador" que se encarga de transformar as plantillas (compoñentes) de Vue en código JavaScript optimizado que utilizará o navegador para visualizar a páxina, encargándose de procesar as plantillas e os datos para producir o contido.


As distribucións de desenvolvemento de ''Vue'' inclúen o compilador o que permite escribir as plantillas no HTML ou en ficheiros .vue sepearados sen compilalos previamente. Unha vez rematada a aplicación se "compilan" (build) xerando a aplicación de produción mediante o comando """npm run build"""
As distribucións de desenvolvemento de ''Vue'' inclúen o compilador, polo que podemos crear e probar a aplicación con ficheiros individuais cos distintos compoñentes da nosa web (arquivos .vue) e probala mediante '''''npm run dev'''''. Con Vue normalmente ven integrado un xestor de proxectos (Vite e Vue CLI) que ademais proporciona un servidor web para poder ir probando o desenvolvemento.


Unha vez rematado o frontend, se "compila" (build) xerando o frontend de produción mediante o comando '''''npm run build'''''. Este comando xerará unha versión da distribución da web dentro da carpeta build que podemos copiar ao raiz do noso servidor de produción.
As distribucións de produción non precisan o compilador, xa que a aplicación xa estará "compilada" a JavaScript.


==Elaboración dun Front-End con Vue==
O punto de entrada dunha aplicación """Vue""" é normalmente un arquivo chamado """main.js""" (ou """main.ts""" se estás utilizando TypeScript). Este arquivo é onde se crea e configura a instancia da aplicación Vue e se monta nun elemento HTML
===Instalación da contorna de desenvolvemento ===
Para desenvolver un frontend con Vue o mais apropiado e o uso do xestor de paquetes '''npm''' dentro da carpeta onde imos desenvolver o frontend, que non ten nada que ver coa carpeta onde se instalará o servizo web de producción.
<syntaxhighlight lang="html">
npm create vue@latest
</syntaxhighlight>


Mediante este comando se recopilan todos os módulos necesarios para o desenvolvemento e creación de frontend realizando unha serie de preguntas sobre as tecnoloxías que queremos empregar. E recomendable o uso de TypeScript e ESLint. Normalmente o axeitado e desenvolver mediante VSCode, xa que trae plugins que fan cómodo o desenvolvemento. Vue instalará un compoñente de "Benvida", que será o "frontend por defecto"
Un exemplo de main.ts sería o seguinte:


Unha vez executado ese comando, se crea a lista de software necesario que podemos instalar no proxecto
<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
npm install
// Usamos bootstrap para os estilos a nivel global. Se carga de node_modules
</syntaxhighlight>
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';


A estrutura da aplicación na carpeta será similar a esta:
import App from '@/App.vue'; // En esta plantilla reside a páxina principal da aplicación. @ representa a carpeta src da instalación de Vue.
<syntaxhighlight>
<proxecto>/
├── index.html // Archivo HTML principal
├── src/ // Carpeta de código fuente
│ ├── assets/ // Archivos estáticos (imágenes, etc.)
│ ├── components/ // Componentes de Vue
│ ├── views/ // Vistas de la aplicación
│ ├── App.vue // Componente raíz
│ └── main.js // Archivo de entrada de JavaScript
├── package.json
└── vite.config.ts
└── eslint.config.ts
</syntaxhighlight>

'''index.html''' e o punto de carga do frontend de desenvolvemento (unha vez compilado con '''''npm run prod''''', se creará unha versión de index.html preparada para o despregamento na carpeta build). O desenvolvemento terá lugar na carpeta '''src''', que se identificará no proxecto como a carpeta @ para as rutas.

Dentro da carpeta '''src''' temos o punto de entrada do frontend Vue, que é o arquivo ''main.ts'' ou ''main.js'' (dependendo de si utilizamos JavaScript ou TypeScript) e '''''App.vue''''' que é o compoñente principal que "debuxará" o frontend a presentar dentro do ''index.html'' da páxina.

En App.vue teremos o frontend que se amosará si lanzamos a versión de desenvolvemento mediante '''''npm run dev''''',

Si queremos poder acceder cun cliente remoto (en outra máquina) debemos modificar a información do ficheiro '''vite.config.ts''':
<syntaxhighlight lang="html">
vite.config.ts:
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server: {
host: '0.0.0.0', // Escoitar en todas as interfaces
port: 8000, // O porto no que se esperan conexións
strictPort: true, // Opcional: fallará si o porto xa está en uso
},
})
</syntaxhighlight>

O punto de entrada dunha aplicación """Vue""" é normalmente un arquivo chamado """main.js""" (ou """main.ts""" se estás utilizando TypeScript). Este arquivo é onde se crea e configura a instancia da aplicación Vue e se monta nun elemento HTML-

=== Internacionalización===
Si queremos que o noso frontend soporte varios idiomas necesitaremos o módulo ''vue-i18n'' que podemos instalar con '''npm install vue-i18n'''. Este módulo nos proporcionará a posibilidade de utilizar diccionarios en JSON nos que estarán as traduccións das distintas cadeas de texto do front-end situados en '''src/locales''' como ''es.json'', ''gl.json'' ou ''en.json''.
<syntaxhighlight lang="html">
{
"Configure":"Configurar",
"Log Out":"Saír",
"Log In": "Iniciar Sesión",
"User":"Usuario",
"Password":"Contrasinal",
"Did you forget your password?":"¿ Esqueciches o teu contrasinal ?",
"Incorrect username or password":"Usuario ou contrasinal incorrectas",
}
</syntaxhighlight>

Será necesario a carga do módulo '''i18n''' no programa principal '''main.ts''', que pode quedar algo similar a esto:
<syntaxhighlight lang="html">
import App from '@/App.vue';
import { createApp } from 'vue';
import { createApp } from 'vue';
import { createI18n } from 'vue-i18n'; // Importamos o sistema de internacionalización
import { createI18n } from 'vue-i18n';


// Cargamos as cadeas de localización de texto da aplicación
import en from '@/locales/en.json';
import en from '@/locales/en.json';
import es from '@/locales/es.json';
import es from '@/locales/es.json';
import gl from '@/locales/gl.json';
import gl from '@/locales/gl.json';


// Dispoñemos destes tres idiomas
const messages={ en, es, gl };
const messages={ en, es, gl };


// Collemos por defecto a linguaxe do navegador
// Tomamos como linguaxe inicial o do naegador ou galego
const userLocale = navigator.language || 'gl';
const userLocale = navigator.language || 'gl';


// Crear a instancia de i18n e definindo o idioma predeterminado
// Crear a instancia de i18n e definir o idioma predeterminado
const i18n = createI18n({
const i18n = createI18n({
locale: userLocale, // Idioma predeterminado
locale: userLocale, // Idioma predeterminado
fallbackLocale: 'en', // Si non temos mensaxe traducida, usamos a do diccionario en inglés.
fallbackLocale: 'en', // Si non atopamos no idioma actual, usamos este
messages, // Recursos de tradución
messages, // Recursos de tradución
numberFormats: {
numberFormats: {
Liña 44: Liña 114:
});
});


const app=createApp(App); // Creamos a aplicación usando App.vue que importamos ao inicio
const app=createApp(App).use(i18n).mount('#app')
app.use(i18n); // Imos usar internacionalización
app.mount('#app') // "Montamos" o compoñente definido por App.vue no id #app do index.html

</syntaxhighlight>
</syntaxhighlight>


Isto nos proporcionará nas plantillas o método '''$t()''', que se encargará de substituír o texto entre paréntese polo lido do dicionario.
Ese código cargará os JSON definindo as traducións das cadeas de texto do programa en formato JSON ({"cadea de texto":"tradución",....}), cargará o compoñente Vue ""App.vue"" e o presentará dentro do elemento con id "app" no index.html da aplciación.

===Os Compoñentes Vue===
Os frontends construídos en Vue comezan no script ''main.ts ou main.js'' coa creación dunha intancia de aplicación mediante a función '''createApp'''. Esa aplicación consiste nun compoñente que se incrustará nun elemento do DOM de index.html. Ese compoñente pode facer uso a súa vez de outros compoñentes para conformar o frontend. Aínda que un frontend pode ter varias aplicacións cada unha co seu compoñente raíz, o habitual e ter unha única aplicación.

Un SFC (Single File Component) de Vue, como suxire o nome, encapsula a lóxica do compoñente (JavaScript), a plantilla (HTML) e os estilos (CSS) nun único ficheiro normalmente coa extensión '''.vue'''


Un exemplo de compoñente Vue mínimo pode ser este:
Un exemplo de compoñente Vue (Vue.js) mínimo que pode ser "incrustado" pode ser este:


<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
Liña 58: Liña 130:
const nome="O meu primeiro compoñente Vue";
const nome="O meu primeiro compoñente Vue";
</script>
</script>
<template>
<template>
Hola Mundo!!! {{ nome }}
Hola Mundo!!! {{ nome }}
</template>
</template>
<style scoped>
<style scoped>
</style>
</style>
</syntaxhighlight>


O contido do main.js, podería ser o seguinte:
<syntaxhighlight lang="html">
import { createApp } from 'vue'
// import the root component App from a single-file component.
import App from './App.vue' // Importamos o compoñente

const app = createApp(App) // Creamos a aplicación
app.mount("#app"); // Incrustamos o compoñente Vue no index.html no elemento con id "app"
</syntaxhighlight>
</syntaxhighlight>


Como podemos observar no compoñente Vue, se aprecian tres seccións diferentes:
''Vue'' pode utilizar dous tipos de API diferentes no deseño dos compoñentes:
;<script setup>: Esta sección contén o código javascript que se levará a cabo cando se "monte" o compoñente na páxina, o que normalmente sucede unha única vez. Os compoñentes poden recibir parámetros dende main.ts ou main.js ou dende outro código javascript dun compoñente.
;<template>: Contén a plantilla HTML que producirá a presentación a ser incrustada na páxina, reemplazando a información na plantilla segundo a linguaxe de plantillas de Vue.
;<style>: Conten o código CSS para a plantilla indicada en <template> Si especificamos ''scoped'' os estilos aquí especificados unicamente serán efectivos para esta plantilla, si non, serán efectivos de xeito global.

=== Options API ===
=== Options API ===
Options API é un dos sistemas de deseño de compoñentes que pode usar Vue. Options API é o "modo tradicional", e consiste en definir a lóxica dun compoñente usando un obxecto javascript con distintos métodos e atributos que cubren o ciclo de vida e funcionalidades do compoñente:
Coa Options API, definimos a lóxica dun compoñente usando un obxecto de opcións, como data, methods e mounted. As propiedades definidas polas opcións están dispoñibles en this dentro das funcións, que apunta á instancia do compoñente:
;name: Este '''atributo''' indica o nome do compoñente.
<syntaxhighlight lang="html">
;data(): Este '''método''' define o estado reactivo local do compoñente. Retorna un obxecto coas propiedades que desexamos sexan empregados no procesamento da plantilla de xeito reactivo.
<script>
;created(): Este '''método''' se executa cando o compoñente é creado.
export default {
;mounted(): Este '''método''' se executa cando o compoñente é montado no DOM.
// Properties returned from data() become reactive state
;updated(): Este '''método''' se executa cada vez que é necesario actualizar a plantilla.
// and will be exposed on `this`.
;destroyed(): Este '''método''' se executa cada vez que o compoñente se elimina.
data() {
;provide() / inject: O '''método provide()''' permite compartir datos entre compoñentes "pais" e "fillos". ''provide()'' Debe retornar un obxecto onde se especifique como atributos a información a compartir. Esta información pode ser accedida polos fillos mediante o '''atributo inject''', que indicará nun array o conxunto de datos "provided" a utilizar.
return {
;props: Este '''atributo''' especifica os datos (parámetros) que pode recibir o compoñente cando é "incluído" na web.
count: 0
;computed: Este '''atributo''' almacena un obxecto que contén métodos que podemos especificar como atributos na plantilla, deste xeito podemos eliminar a lóxica da plantilla deixandoa máis limpa e fácil de manter.
}
;methods: Este '''atributo''' almacena un obxecto que contén métodos que podemos chamar dende a plantilla, principalmente como xestores de eventos. Si queremos, podemos usar para o método o mesmo identificador que o atributo que queremos "recalcular", de xeito que se refrescará cando o valor do atributo cambie.
},
;watch: Este '''atributo''' almacena un obxecto que contén métodos que "observan" certas propiedades, executando un método cando se produce un cambio. Debemos identificar o método co mesmo nome que o atributo que queremos vixiar, e recibirá como parámetros o valor futuro e o valor actual.
;components: Este '''atributo''' almacena un obxecto que contén compoñentes dos que queremos poder facer uso no compoñente actual.
;mixins: Este '''atributo''' é un array que permite reutilizar funcionalidade para que sexa utilizada en varios compoñentes. Permiten compartir métodos, datos e ciclo de vida entre diferentes compoñentes. En primeiro lugar, se debe crar o "mixin" que consistirá nunha variable que almacene un obxecto coa información a reutilizar. Esa información se poderá utilizar en novos compoñentes especificando os mixin desexados no seu atributo mixins.
;directives: Este atributo almacena obxectos que almacena métodos a aplicar a elementos concretos do DOM en unha frase concreta do ciclo de vida do compoñente (hooks). Os elementos que especifiquen v-[metodo] executarán a directiva no hook indicado que pode ser '''created,beforeMount,mounted,beforeUpdate,updated,beforeUmount e unmounted".
;extends: Este '''atributo''' permite especificar un compoñente base do que se herdan as funcionalidades. E similar aos mixin, pero indicando un único compoñente.
;inheritAttrs: Este '''atributo''' booleano controla a herdanza dos atributos. Por defecto os atributos especificados nun compoñente incluído que non son declarados como propiedades, se inclúen como atributos no elemento raíz do template, engadíndose as existentes si é o caso. Especificando '''false''' evitamos este comportamento, pero serán accesibles co prefixo "$" <nowiki>{{ $attr }}</nowiki>
;emits:Este '''atributo''' é un array que conten un conxunto de métodos que "poden ser emitidos" mediante '''''this.$emit'''''. Este evento pode ser capturado co atributo ''@evento'' na chamada ao compoñente.
;template: Este '''atributo''' almacena a plantilla a ser transformada en HTML e incrustada no DOM. Tamén pode indicarse fora do script entre <template> e </template>. A template define o documento a ser incrustado no DOM unha vez procesado coa información producida pola sección <script> e aplicando o estilo especificado na sección <style>. A reactividade garante que si os datos cambian, o template é procesado de novo para xerar unha nova saida.


=== Composition API ===
// Methods are functions that mutate state and trigger updates.
Coa Composition API utilízamos normalmente <script setup> para indicar o JavaScript a utilizar na inicialización do componente. Outra posibilidade é especificar un método setup() co mesmo código.
// They can be bound as event handlers in templates.
Si queremos que o compoñente poda recibir parámtros, os debemos especificar mediante o atributo '''props''', que conten un obxecto que indica todos os atributos que se poden recibir cando se chama ao compoñente.
methods: {
Todos os parámetros declarados en ''props'' son reactivos. En esta API podemos seleccionar que outros datos queremos que sexan reactivos de modo específico mediante os métodos'''ref''' ou '''reactive''' (en options API, os datos se teñen que declarar en data() e sempre son reactivos).
increment() {
this.count++
}
},


'''ref''' é axeitado para datos simples, mentres que '''reactive''' é máis axeitado para obxectos complexos, que podan ter outros obxectos como atributos que tamén queremos que sexan reactivos. Cando definimos un dato como reactivo mediante o método '''ref''' necesitaremos usar o atributo ''.value'' para acceder ao seu valor. Outra posibilidade é '''shallowRef''' (que simplemente comproba si cambia a referencia do obxecto, en lugar do obxecto en sí).
// Lifecycle hooks are called at different stages
// of a component's lifecycle.
// This function will be called when the component is mounted.
mounted() {
console.log(`The initial count is ${this.count}.`)
}
}
</script>


Nos compoñentes con compositionAPI podemos definir as funcionalidades desexadas mediante métodos javascript. Estas funcionalidades simplemente variarán valores reactivos que provocan o repintado e polo tanto o "recálculo" da plantilla. Todo o código irá dentro do método setup(), ou si queremos unha sintaxe mais simple, dentro de <script setup>
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>
</syntaxhighlight>
=== Composition API ===
Coa Composition API, definimos a lóxica dun compoñente usando funcións da API importadas. Nos SFCs (Single File Components), a Composition API utilízase normalmente con <script setup>. O atributo setup é unha indicación que permite a Vue realizar transformacións en tempo de compilación que nos permiten usar a Composition API con menos código repetitivo. Por exemplo, as importacións e as variables/funcións de nivel superior declaradas en <script setup> son directamente utilizables na plantilla.


Vexamos un exemplo de compoñente:
Na maioría dos proxectos de Vue habilitados para ferramentas de construción, autoramos compoñentes de Vue utilizando un formato de ficheiro semellante ao HTML chamado Compoñente de Ficheiro Único (tamén coñecido como ficheiros ''*.vue'', abreviado como '''SFC'''). Un SFC de Vue, como suxire o nome, encapsula a lóxica do compoñente (JavaScript), a plantilla (HTML) e os estilos (CSS) nun único ficheiro.


<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
Liña 132: Liña 210:
font-weight: bold;
font-weight: bold;
}
}
</style>
</syntaxhighlight>
</syntaxhighlight>


Os hook da composition API son maiores que en Options API: setup(), onMounted(), onUpdated(), onUnmounted(), onBeforeMount(), onBeforeUpdate(), onBeforeUnmount, onErrorCaptured, onActivated, onDeactivated(),


Ambos os estilos de API son plenamente capaces de cubrir casos de uso comúns. Son interfaces diferentes impulsadas polo mesmo sistema subxacente. De feito, a Options API está implementada sobre a Composition API. Os conceptos fundamentais e o coñecemento sobre Vue son compartidos entre os dous estilos.
Ambos os estilos de API son plenamente capaces de cubrir casos de uso comúns. Son interfaces diferentes impulsadas polo mesmo sistema subxacente. De feito, a Options API está implementada sobre a Composition API. Os conceptos fundamentais e o coñecemento sobre Vue son compartidos entre os dous estilos.
Liña 147: Liña 227:


Neste documento utilizaremos principalmente Composition API.
Neste documento utilizaremos principalmente Composition API.
== Comezando con plantillas en Vue ==
Vue utiliza unha sintaxe de templates baseada en HTML que che permite ligar de forma declarativa o DOM renderizado cos datos subxacentes da instancia do compoñente. Todos os templates de Vue son sintacticamente HTML válido, que pode ser analizado por navegadores compatibles co estándar e parsers de HTML.


Por debaixo, Vue compila os templates en código JavaScript altamente optimizado. Combinado co sistema de reactividade, Vue pode determinar de maneira intelixente o número mínimo de compoñentes que precisa volver renderizar e aplicar a mínima cantidade de manipulacións no DOM cando cambia o estado da aplicación.
==Instalación==
Existen varios modos de instalación:
===Inclusión Direta con <script>===
Simplemente se debe descargar e incluír a etiqueta script coa ruta correcta, ou utilizar un CDN. Por exemplo: <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>. '''Vue''' tamén está dispoñible nos CDN unpkg e cdnjs.


As plantillas Vue se definen nos compoñentes dentro das etiquetas <template>...</template> e dispoñen dunha linguaxe de procesado de plantillas bastante simple e potente que procesará a información procesada na sección <script>:
As distribucións de Vue teñen a forma '''vue(.runtime).global(.prod).js''', donde "runtime" conten únicamente o JavaScript necesario para executar as plantillas xa "compiladas" a JavaScript, mentres que as outras inclúen o compilador necesario para a "compilación" das plnatillas ''.vue''.


====Interpolación de Texto====
Para o uso de módulos ES nativos e de xeito similar, a compilación de Vue a usar ten a forma '''vue(.runtime).esm-browser(.prod).js'''.
A forma máis básica de vinculación de datos é a interpolación de texto utilizando a sintaxe de "mostacho" (dobres chaves):
<syntaxhighlight lang="html">
<template>
<span>Message: {{ msg }}</span>
</template>
</syntaxhighlight>


A etiqueta de mostacho será substituída polo valor da propiedade `msg` da instancia do componente correspondente. Ademais, actualizarase cada vez que a propiedade `msg` cambie.
Si usamos empaquetadores como webpack, rollup ou parcel, temos as versións '''vue(.runtime).esm-bundler.js'''


====Vinculación de Atributos====
As versións de produción inclúen ''prod'';
As chaves non se poden usar dentro dos atributos HTML. En vez diso, usa a directiva `v-bind`:


Existen distintas compilacións de Vue:

*'''Global Build''': Na ''Global Build'' odas as APIs de nivel superior están expostas como propiedades no obxecto global Vue.
<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<template>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div v-bind:id="dynamicId"></div>
</template>
</syntaxhighlight>


A directiva `v-bind` indica a Vue que mantén o atributo id do elemento sincronizado coa propiedade `dynamicId` do compoñente. Se o valor vinculado é `null` ou `undefined`, o atributo será eliminado do elemento renderizado.
<div id="app">{{ message }}</div>


Sintaxe Abreviada
<script>
Como `v-bind` se usa con moita frecuencia, ten unha sintaxe abreviada dedicada:
const { createApp, ref } = Vue


<syntaxhighlight lang="html">
createApp({
<template>
setup() {
<div :id="dynamicId"></div>
const message = ref('Hello vue!')
</template>
return {
message
}
}
}).mount('#app')
</script>
</syntaxhighlight>
</syntaxhighlight>


====HTML Crudo====

As dobres chaves interpretan os datos como texto sin formato, non como HTML. Para saír HTML real, necesitas usar a directiva `v-html`:
*'''ES Module Build''': E o formato preferido para as aplicacións Vue, Utiliza módulos ECMAScript (ESM). Este enfoque permite importar Vue e outros módulos de forma máis flexible e organizada, facilitando a xestión de dependencias e a estrutura do código. Os ES Modules son compatibles co estándar moderno de JavaScript, e permiten realizar importacións e exportacións explícitas entre diferentes ficheiros. Usa a sintaxe de importación (import Vue from 'vue';), permitindo unha organización máis clara do código e un mellor control das dependencias.


<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<template>
<div id="app">{{ message }}</div>
<p>Usando interpolación de texto: {{ rawHtml }}</p>
<p>Usando a directiva v-html: <span v-html="rawHtml"></span></p>
</template>
</syntaxhighlight>


====Atributos Booleanos====
<script type="module">
Os atributos booleanos son atributos que poden indicar valores verdadeiros/falsos pola súa presenza nun elemento. Por exemplo, `disabled` é un dos atributos booleanos máis comúns.
import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'


`v-bind` funciona dun xeito algo diferente neste caso:
createApp({

setup() {
<syntaxhighlight lang="html">
const message = ref('Hello Vue!')
<template>
return {
<button :disabled="isButtonDisabled">Button</button>
message
</template>
}
}
}).mount('#app')
</script>
</syntaxhighlight>
</syntaxhighlight>


O atributo `disabled` incluirase se `isButtonDisabled` ten un valor verdadeiro. Tamén se incluirá se o valor é unha cadea de texto vacía, mantendo a coherencia con `<button disabled="">`. Para outros valores falsos, o atributo será omxido.
Na demostración anterior, estamos importando desde a URL completa do CDN, pero no resto da documentación verás código como este:

====Vinculación dinámica de múltiples atributos====

Se tes un obxecto de JavaScript que representa múltiples atributos e que ten a seguinte estrutura:


<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
const objectOfAttrs = {
import { createApp } from 'vue'
id: 'container',
class: 'wrapper',
style: 'background-color:green'
}
</syntaxhighlight>
</syntaxhighlight>


Podes vinculalos a un único elemento utilizando `v-bind` sen un argumento:
Podemos ensinar ao navegador onde localizar a importación de Vue utilizando *Import Maps*:


<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<div v-bind="objectOfAttrs"></div>
<script type="importmap">
</syntaxhighlight>
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>


====Usando expresións de JavaScript====
<div id="app">{{ message }}</div>


Até agora, só vinculamos claves de propiedades sinxelas nas nosas plantillas. Pero Vue realmente admite toda a potencia das expresións de JavaScript dentro de todas as vinculaciones de datos:
<script type="module">
import { createApp, ref } from 'vue'


<syntaxhighlight lang="html">
createApp({
{{ number + 1 }}
setup() {

const message = ref('Hello Vue!')
{{ ok ? 'SÍ' : 'NON' }}
return {

message
{{ message.split('').reverse().join('') }}
}

}
<div :id="`list-${id}`"></div>
}).mount('#app')
</script>
</syntaxhighlight>
</syntaxhighlight>


Estas expresións serán avaliadas como JavaScript no ámbito de datos da actual instancia do componente. As comiñas invertidas ` na última expresión, permiten incluir variables para crear un texto pechadas con ${}.
=== Creación dunha aplicación Vue con Node ===
Vue proporciona un completo framework baseado en Node.js co que podemos desenvolver unha aplicación, "compilar" as plantillas e conseguir unha versión final de distribución. Para iso se empregan unha serie de utilidades (build tools) que nos axudarán nas distintas fases do proxecto. Unha desas ferramentas é '''Vite'''.


Nas plantillas de Vue, as expresións de JavaScript pódense usar nas seguintes posicións:
''Vite'' é unha ferramenta de desenvolvemento de front-end moderna que se utiliza para a creación de aplicacións web rápidas e eficientes. Foi creada por Evan You, o mesmo creador de ''Vue.js'', aínda que ''Vite'' non está limitado só a ''Vue'', xa que tamén soporta outros frameworks como ''React''.


- Dentro das interpolacións de texto (mustaches)<br/>
A función de ''Vite'' dentro do ecosistema Vue é a "compilación" das plantillas (ES Modules) durante o desenvolvemento e a optimización final para producción.
- No valor dos atributos de calquera directiva de Vue (atributos especiais que comezan con `v-`)


====Chamando funcións====
En primeiro lugar, se debe crear a estrutura da aplicación mediante o uso de xestores de paquetes JavaScript como '''npm'' (Node Package Manager) ou '''yarn'' (Yet Another Resource Negotiator) entre outros:

É posible chamar a un método exposto por un componente dentro dunha expresión de vinculación:


<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<time :title="toTitleDate(date)" :datetime="date">
npm create vue@latest
{{ formatDate(date) }}
</time>
</syntaxhighlight>
</syntaxhighlight>


# ''':title="toTitleDate(date)"''': O atributo title establécese de forma dinámica mediante v-bind, utilizando a sintaxe abreviada :. Isto indica que title tomará o seu valor do resultado da chamada ao método toTitleDate(date).
Durante a configuración inicial da aplicación o sistema nos preguntará detalles como:
#* '''toTitleDate(date)''': Este método debería estar definido no compoñente, ben na sección methods (en Options API) ou directamente na función setup (en Composition API). A súa finalidade é formatear a data (date) nunha cadea que será usada como valor do atributo title. Por exemplo, toTitleDate podería devolver algo como "20 de Outubro de 2024" para amosar unha data legible cando o usuario poña o cursor enriba do tempo.
* '''o nome do proxecto''
# ''':datetime="date"''': Aquí tamén se usa v-bind para ligar o valor do atributo datetime a unha variable date. Isto fai que datetime reciba directamente o valor de date. O atributo datetime en etiquetas <time> require un formato específico (xeralmente o formato ISO 8601, como 2024-10-20T00:00:00Z), xa que axuda a indicar a data exacta para fins de SEO e accesibilidade.
* '''si imos usar TypeScript'''
# '''<nowiki>{{ formatDate(date) }}</nowiki>''': O contido dentro da etiqueta <time> utiliza formatDate(date) para amosar a data formateada.
*'''si queremos JSX''' (unha extensión para escribir capas de presentacón dentro do JavaScript para crear interfaces demasiado complexas para as plantillas)
#* '''formatDate(date)''': Este método, similar a toTitleDate, debería estar definido no compoñente e pode transformar date nun formato amigable para o usuario, como "20/10/2024".
*'''si queremos usar Vue-Router''' (que nos facilita a creación de SPA a través de rutas para a transición entre compoñentes para presentar o contido solicitado ao servidor)
*'''si queremos usar Plinia''' (que nos permite compartir o estado --información-- entre distintos compoñentes da aplicación Vue)
*'''si queremos usar Vitest''' (que é un framework para a realización de tests unitarios ''')
*'''si queremos engadir un sistema de Testing''' (nos ofrece Cypress, Nightwatch ou Playwrigth)
*'''si queremos usar ESLint''' (analiza problemas de estilo, erros de sintaxe, se xera a configuración para VSCode e podemos utilizalo dende a liña de comandos con '''npx eslint .''' ou '''npx eslint . --fix'''. Mediante npx podemos executar paquetes instalados con npm sen instalalos no sistema)
*'''si queremos usar Prettier''' (formatea o código revisando tabuladores, espazos.. de xeito que quede lexible)
*'''si queremos usar as extensións de depuración de Vue'''


As funcións chamadas dentro das expresións de vinculación serán executadas cada vez que o componente se actualice, polo que non deben ter efectos secundarios, como cambiar datos ou acender operacións asincrónicas.
Unha vez iniciado o proxecto o sistema nos indicará:
As expresións de plantilla están illadas e só teñen acceso a unha lista restrinxida de globais. A lista expón globais incorporados de uso común como Math e Date.
<syntaxhighlight lang="bash">
Done. Now run:


====Directivas====
cd "<proxecto>"

npm install
As directivas son atributos especiais co prefijo `v-`. Vue proporciona unha serie de directivas incorporadas, incluíndo `v-html` e `v-bind.
npm run dev

Os valores dos atributos das directivas esperan ser expresións de JavaScript únicas (con excepción de `v-for`, `v-on` e `v-slot`). O traballo dunha directiva é aplicar actualizacións de forma reactiva no DOM cando o valor da súa expresión cambia. Tomemos como exemplo `v-if`:

<syntaxhighlight lang="html">
<p v-if="seen">Agora me ves</p>
</syntaxhighlight>
</syntaxhighlight>


Neste caso, a directiva `v-if` eliminaría ou inseriría o elemento <nowiki><p></nowiki> en función da veracidade do valor da expresión lóxica ''seen''. Outras directivas son:
*'''npm install''' instalará todos os módulos JavaScript necesarios para Vue
*'''v-on''': Para xestionar eventos de usuario
*'''npm run dev''' lanzará unha instancia do servidor web de Node para probar o noso proxecto. Inicialmente so aceptará conexións en localhost. Para cambiar a configuración deste servidor de desenvolvemento debemos modificar o arquivo '''vite.config.ts''':
*'''v-for''': Para procesar listas de datos de xeito repetitivo (producindo grupos de elementos HTML na plantilla)
*'''v-slot''': Para pasar contido de plantilla dende o pai ao fillo

==== v-on ====
A directiva v-on úsase para xestionar eventos de usuario, como pulsar un botón ou escribir nun campo de texto, e permite executar métodos específicos ao detectar eses eventos. Pódese abreviar usando @.


<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<button v-on:click="saudar">Prema aquí</button></syntaxhighlight>
import { fileURLToPath, URL } from 'node:url'


Isto asocia o evento click co método saludar, que debería estar definido no compoñente na seccion <nowiki><script setup></nowiki>.
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'


<syntaxhighlight lang="html">
// https://vite.dev/config/
<button @click="saludar">Prema aquí</button></syntaxhighlight>
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server: {
host: '0.0.0.0', // Escuchar en todas las interfaces
port: 8000, // O el puerto que estés utilizando
strictPort: true, // Opcional: fallará si el puerto ya está en uso
},
})


</syntaxhighlight>
<syntaxhighlight lang="html">
<button @click="incrementar(5)">Incrementar</button></syntaxhighlight>


;Prevención de comportamento por defecto: Para evitar o comportamento por defecto dun evento (como o envío dun formulario), úsase o modificador .prevent na plantilla HTML: <nowiki><form @submit.prevent="procesarFormulario">...</form></nowiki>. Outros modificadores posibles para usar na xestión de eventos na plantila son:
O esquema do proxecto será similar a este:
*'''.stop''':Evita a propagación do evento a través dos elementos pai.
<syntaxhighlight>
*'''.self''':Unicamente atende a eventos producidos no propio elemento, sin facer caso a os elementos fillos
<proxecto>/
*'''.capture''':Indica que os eventos de este tipo producidos nos elementos interiores son xestionados por este método.
*'''.once''': Soamente se permite o evento unha vez.
├── index.html // Archivo HTML principal
*'''.passive''': Indica que se procesará o evento nativamente sen esperar a que se execute o xestor indicado
├── src/ // Carpeta de código fuente

│ ├── assets/ // Archivos estáticos (imágenes, etc.)
Os eventos de teclado, de xeito similar poden levar ''.enter, .page-dowwn, .tab, .delete, .esc, .space, .up, .down, .left, .right,.ctrl,.alt,.shift,.meta'' identificando a tecla pulsada'' e os de rato ''.left, right ou .middle'' identificando o botón pulsado.
│ ├── components/ // Componentes de Vue

│ ├── views/ // Vistas de la aplicación
====v-for====
│ ├── App.vue // Componente raíz
A directiva v-for é empregada para renderizar listas e repetir un compoñente ou elemento en función dunha colección de datos, como un array. Require que se especifique un key único en cada elemento renderizado.
│ └── main.js // Archivo de entrada de JavaScript

<syntaxhighlight lang="html">
├── package.json
<ul>
└── ...
<li v-for="elemento in lista" :key="elemento.id">{{ elemento.nome }}</li>
</ul>
</syntaxhighlight>
</syntaxhighlight>


Neste caso, lista debería ser unha colección de obxectos definida no compoñente en <nowiki><script setup></nowiki>, e cada elemento sería renderizado cun valor de id único. Tamén se pode usar o índice da colección de elementos:
Para crear a aplicación que serviremos mediante un Apache, debemos construila con '''npm run build''' e instalar o contido da carpeta build no root do sitio web. Debemos habilitar o módulo ''rewrite'' para que funcionen as rutas de Vue.


Unha aplicación básica tería o seguinte aspecto:
*'''index.htnl'''
<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<ul>
<!DOCTYPE html>
<li v-for="(elemento, índice) in lista" :key="índice"> {{ índice }} - {{ elemento.nome }} </li>
<html lang="es">
<head>
</ul>
</syntaxhighlight>
<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hola Mundo con Vue 3</title>


Ou utilizar obxectos e as súas propiedades:
</head>
<syntaxhighlight lang="html">
<body>
<ul>
<div id="app"></div> <!-- Elemento donde se montará la aplicación -->
<li v-for="(valor, chave) in obxecto" :key="chave">{{ chave }}: {{ valor }}</li>
<script type="module" src="/src/main.ts"></script>
</ul>
</script>
</body>
</html>
</syntaxhighlight>
</syntaxhighlight>


==== v-slot ====
* '''/src/App.vue'''
A directiva v-slot permite crear e pasar contidos personalizados a compoñentes fillo desde o pai, mellorando a modularidade ao permitir especificar diferentes partes do contido dende o compoñente pai.

<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<script setup>
import Module from './components/Module/Module.vue'
const nombre="Test para Iass Cloud";
</script>

<template>
<template>
<div> <slot></slot> </div>
<Module msg="You did it!" />
{{ nombre }} Hola Mundo!
</template>
</template>
</syntaxhighlight>
</syntaxhighlight>


Usalo dende o compoñente pai: '''''MeuCompoñente''''' na sección <nowiki><template></nowiki>
* '''/src/compoents/Module/Module.vue'''
<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<MeuCompoñente>
<style src="@/components/Module/module.css" scoped></style> <!-- Importar CSS específico del componente -->
<p>Este parágrafo será amosado dentro do slot do compoñente.</p>

</MeuCompoñente>
<script setup lang="ts">
</syntaxhighlight>
defineProps<{msg: string}>()
</script>


; Os slots con nome permiten crear varios slots con nomes específicos:
<syntaxhighlight lang="html">
<template>
<template>
<header>
<h1> {{msg}} It's Work - Has a background icon ?</h1>
<slot name="cabeceira"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="pé"></slot>
</footer>
</template>
</template>
</syntaxhighlight>
</syntaxhighlight>


Que se utilizaría do seguinte xeito:
En este contexto, o marcador @ indica nas URL a carpeta /src do proxecto, e se pode usar como inicio de acceso aos recursos dentro de /src

=== Controlando os Erros da Aplicación ===
En app.config.* dispoñemos de varios elementos Vue que nos proporcionan control sobre o comportamento xeral da aplicación.
Por exemplo, se poden "capturar" todos os erros sin xestionar que se produzan na aplicación mediante un código simple.

*'''app.config.errorHandler''': Recibe todos os errores non xestionados. O errorHandler recibe como argumentos o erro, a instancia do compoñente que lanzou o erro e un string explicativo sobre o erro

<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<MeuCompoñente>
interface AppConfig {
<template v-slot:cabeceira> <h1>Cabeceira personalizada</h1> </template>
errorHandler?: (
<p>Este é o contido principal.</p>
err: unknown,
<template v-slot:pé> <p>Pé de páxina personalizado</p> </template>
instance: ComponentPublicInstance | null,
</MeuCompoñente>
// `info` is a Vue-specific error info,
// e.g. which lifecycle hook the error was thrown in
info: string
) => void
}
</syntaxhighlight>
</syntaxhighlight>


Isto produciría un HTML co contido definido insertado nos slots correspondentes en MeuCompoñente.
Se utilizaría do seguinte xeito...


Tamén é posible pasar e utilizar datos cos slots:
<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<template>
app.config.errorHandler = (err, instance, info) => {
<slot :datos="datosExemplo"></slot>
// handle error, e.g. report to a service
</template>
}
</syntaxhighlight>
</syntaxhighlight>


Que poderíamos utilizar así:
*'''app.config.warnHandler''': Xestiona avisos (warnings) de Vue

<syntaxhighlight lang="html">
<syntaxhighlight lang="html">
<MeuCompoñente v-slot="{ datos }">
interface AppConfig {
<p>Os datos pasados son: {{ datos }}</p>
warnHandler?: (
</MeuCompoñente>
msg: string,
instance: ComponentPublicInstance | null,
trace: string
) => void
}
</syntaxhighlight>
</syntaxhighlight>
== Facendo consultas ao servidor: Axios ==
Aquí tes un breve titorial en galego normativo sobre o uso de Axios, unha libraría popular en JavaScript para realizar solicitudes HTTP de forma sinxela e eficiente:


Instalación de Axios
que se utilizaría do seguinte xeito:
Para comezar a usar Axios nun proxecto, primeiro debes instalalo. Se estás usando npm, executa o seguinte comando no terminal:


bash
<syntaxhighlight lang="html">
Copiar código
app.config.warnHandler = (msg, instance, trace) => {
npm install axios
// `trace` is the component hierarchy trace
Para proxectos que usan Vue ou React, Axios intégrase facilmente e non require configuración adicional.
}
</syntaxhighlight>


Realizar unha Solicitude GET
Existen outros hooks que nos permiten modificar as opcions de compilación (app.config.compilerOptions.*) e rexistrar propiedades globais que se poden utilizar dende calquera punto da aplicación mediante app.config.globalProperties
Unha das funcións máis básicas de Axios é a solicitude GET, que permite obter datos dun servidor. Por exemplo, se queremos obter unha lista de usuarios dun endpoint, podemos facelo do seguinte xeito:


javascript
<syntaxhighlight lang="html">
Copiar código
interface AppConfig {
import axios from 'axios';
globalProperties: Record<string, any>
}
</syntaxhighlight>


axios.get('https://api.exemplo.com/usuarios')
que se utilizaría do seguinte xeito:
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Erro ao obter os usuarios:', error);
});
Neste exemplo:


axios.get() envía unha solicitude GET á URL especificada.
<syntaxhighlight lang="html">
.then() xestiona a resposta cando a solicitude é exitosa.
app.config.globalProperties.msg = 'hello'
.catch() xestiona os erros se a solicitude falla.
</syntaxhighlight>
Realizar unha Solicitude POST
== As plantillas en Vue ==
Para enviar datos ao servidor, usamos a solicitude POST. Por exemplo, para crear un novo usuario:
Vue utiliza unha sintaxe de templates baseada en HTML que che permite ligar de forma declarativa o DOM renderizado cos datos subxacentes da instancia do compoñente. Todos os templates de Vue son sintacticamente HTML válido, que pode ser analizado por navegadores compatibles co estándar e parsers de HTML.


javascript
Por debaixo, Vue compila os templates en código JavaScript altamente optimizado. Combinado co sistema de reactividade, Vue pode determinar de maneira intelixente o número mínimo de compoñentes que precisa volver renderizar e aplicar a mínima cantidade de manipulacións no DOM cando cambia o estado da aplicación.
Copiar código
axios.post('https://api.exemplo.com/usuarios', {
nome: 'Xoán',
correo: 'xoan@exemplo.com'
})
.then(response => {
console.log('Usuario creado:', response.data);
})
.catch(error => {
console.error('Erro ao crear usuario:', error);
});
Aquí, enviamos un obxecto JSON con información do usuario que queremos crear.

Configuración de Parámetros e Cabeceiras
Para configurar parámetros ou cabeceiras adicionais, engádeos como terceiro argumento en axios.get() ou axios.post():

javascript
Copiar código
axios.get('https://api.exemplo.com/usuarios', {
params: { id: 123 },
headers: { 'Authorization': 'Bearer token' }
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Erro:', error);
});
Uso de Interceptores
Os interceptores permiten interceptar solicitudes ou respostas antes de que se procesen. Útil para engadir autenticación ou xestionar erros de forma global:

javascript
Copiar código
axios.interceptors.request.use(config => {
config.headers['Authorization'] = 'Bearer token';
return config;
}, error => {
return Promise.reject(error);
});

axios.interceptors.response.use(response => {
return response;
}, error => {
console.error('Erro na resposta:', error);
return Promise.reject(error);
});
Resumo das Funcións Básicas de Axios
axios.get(url, config): Solicitude GET.
axios.post(url, data, config): Solicitude POST.
axios.put(url, data, config): Solicitude PUT para actualizar recursos.
axios.delete(url, config): Solicitude DELETE para eliminar recursos.

Revisión actual feita o 8 de novembro de 2024 ás 20:27

Introdución

Vue (pronunciado /vjuː/, como view) é un framework progresivo para construír interfaces de usuario. A biblioteca central está enfocada só na capa de visualización, e é doada de utilizar e integrar con outras bibliotecas ou proxectos existentes.

Vue dispón dun "compilador" que se encarga de transformar as plantillas (compoñentes) de Vue en código JavaScript optimizado que utilizará o navegador para visualizar a páxina, encargándose de procesar as plantillas e os datos para producir o contido.

As distribucións de desenvolvemento de Vue inclúen o compilador, polo que podemos crear e probar a aplicación con ficheiros individuais cos distintos compoñentes da nosa web (arquivos .vue) e probala mediante npm run dev. Con Vue normalmente ven integrado un xestor de proxectos (Vite e Vue CLI) que ademais proporciona un servidor web para poder ir probando o desenvolvemento.

Unha vez rematado o frontend, se "compila" (build) xerando o frontend de produción mediante o comando npm run build. Este comando xerará unha versión da distribución da web dentro da carpeta build que podemos copiar ao raiz do noso servidor de produción.

Elaboración dun Front-End con Vue

Instalación da contorna de desenvolvemento

Para desenvolver un frontend con Vue o mais apropiado e o uso do xestor de paquetes npm dentro da carpeta onde imos desenvolver o frontend, que non ten nada que ver coa carpeta onde se instalará o servizo web de producción.

npm create vue@latest

Mediante este comando se recopilan todos os módulos necesarios para o desenvolvemento e creación de frontend realizando unha serie de preguntas sobre as tecnoloxías que queremos empregar. E recomendable o uso de TypeScript e ESLint. Normalmente o axeitado e desenvolver mediante VSCode, xa que trae plugins que fan cómodo o desenvolvemento. Vue instalará un compoñente de "Benvida", que será o "frontend por defecto"

Unha vez executado ese comando, se crea a lista de software necesario que podemos instalar no proxecto

npm install

A estrutura da aplicación na carpeta será similar a esta:

<proxecto>/
│
├── index.html            // Archivo HTML principal
├── src/                  // Carpeta de código fuente
│   ├── assets/           // Archivos estáticos (imágenes, etc.)
│   ├── components/       // Componentes de Vue
│   ├── views/            // Vistas de la aplicación
│   ├── App.vue           // Componente raíz
│   └── main.js           // Archivo de entrada de JavaScript
│
├── package.json
└── vite.config.ts
└── eslint.config.ts

index.html e o punto de carga do frontend de desenvolvemento (unha vez compilado con npm run prod, se creará unha versión de index.html preparada para o despregamento na carpeta build). O desenvolvemento terá lugar na carpeta src, que se identificará no proxecto como a carpeta @ para as rutas.

Dentro da carpeta src temos o punto de entrada do frontend Vue, que é o arquivo main.ts ou main.js (dependendo de si utilizamos JavaScript ou TypeScript) e App.vue que é o compoñente principal que "debuxará" o frontend a presentar dentro do index.html da páxina.

En App.vue teremos o frontend que se amosará si lanzamos a versión de desenvolvemento mediante npm run dev,

Si queremos poder acceder cun cliente remoto (en outra máquina) debemos modificar a información do ficheiro vite.config.ts:

vite.config.ts:
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  server: {
        host: '0.0.0.0', // Escoitar en todas as interfaces
        port: 8000, // O porto no que se esperan conexións
        strictPort: true, // Opcional: fallará si o porto xa está en uso
    },
})

O punto de entrada dunha aplicación """Vue""" é normalmente un arquivo chamado """main.js""" (ou """main.ts""" se estás utilizando TypeScript). Este arquivo é onde se crea e configura a instancia da aplicación Vue e se monta nun elemento HTML-

Internacionalización

Si queremos que o noso frontend soporte varios idiomas necesitaremos o módulo vue-i18n que podemos instalar con npm install vue-i18n. Este módulo nos proporcionará a posibilidade de utilizar diccionarios en JSON nos que estarán as traduccións das distintas cadeas de texto do front-end situados en src/locales como es.json, gl.json ou en.json.

{
"Configure":"Configurar",
"Log Out":"Saír",
"Log In": "Iniciar Sesión",
"User":"Usuario",
"Password":"Contrasinal",
"Did you forget your password?":"¿ Esqueciches o teu contrasinal ?",
"Incorrect username or password":"Usuario ou contrasinal incorrectas",
}

Será necesario a carga do módulo i18n no programa principal main.ts, que pode quedar algo similar a esto:

import App from '@/App.vue';
import { createApp } from 'vue';
import { createI18n } from 'vue-i18n';

import en from '@/locales/en.json';
import es from '@/locales/es.json';
import gl from '@/locales/gl.json';

const messages={ en, es, gl };

// Collemos por defecto a linguaxe do navegador
const userLocale = navigator.language || 'gl';

// Crear a instancia de i18n e definir o idioma predeterminado
const i18n = createI18n({
  locale: userLocale, // Idioma predeterminado
  fallbackLocale: 'en',  // Si non atopamos no idioma actual, usamos este
  messages,     // Recursos de tradución
  numberFormats: {
    en: { currency: { style: 'currency', currency: 'USD' } },
    es: { currency: { style: 'currency', currency: 'EUR' } },
    gl: { currency: { style: 'currency', currency: 'EUR' } }
  }
});

const app=createApp(App).use(i18n).mount('#app')

Isto nos proporcionará nas plantillas o método $t(), que se encargará de substituír o texto entre paréntese polo lido do dicionario.

Os Compoñentes Vue

Os frontends construídos en Vue comezan no script main.ts ou main.js coa creación dunha intancia de aplicación mediante a función createApp. Esa aplicación consiste nun compoñente que se incrustará nun elemento do DOM de index.html. Ese compoñente pode facer uso a súa vez de outros compoñentes para conformar o frontend. Aínda que un frontend pode ter varias aplicacións cada unha co seu compoñente raíz, o habitual e ter unha única aplicación.

Un SFC (Single File Component) de Vue, como suxire o nome, encapsula a lóxica do compoñente (JavaScript), a plantilla (HTML) e os estilos (CSS) nun único ficheiro normalmente coa extensión .vue

Un exemplo de compoñente Vue (Vue.js) mínimo que pode ser "incrustado" pode ser este:

<script setup lang="ts">
    const nome="O meu primeiro compoñente Vue";
</script>
<template>  
   Hola Mundo!!! {{ nome }}
</template>
<style scoped>
</style>

O contido do main.js, podería ser o seguinte:

import { createApp } from 'vue'
// import the root component App from a single-file component.
import App from './App.vue'   // Importamos o compoñente

const app = createApp(App) // Creamos a aplicación
app.mount("#app"); // Incrustamos o compoñente Vue no index.html no elemento con id "app"

Como podemos observar no compoñente Vue, se aprecian tres seccións diferentes:

<script setup>
Esta sección contén o código javascript que se levará a cabo cando se "monte" o compoñente na páxina, o que normalmente sucede unha única vez. Os compoñentes poden recibir parámetros dende main.ts ou main.js ou dende outro código javascript dun compoñente.
<template>
Contén a plantilla HTML que producirá a presentación a ser incrustada na páxina, reemplazando a información na plantilla segundo a linguaxe de plantillas de Vue.
<style>
Conten o código CSS para a plantilla indicada en <template> Si especificamos scoped os estilos aquí especificados unicamente serán efectivos para esta plantilla, si non, serán efectivos de xeito global.

Options API

Options API é un dos sistemas de deseño de compoñentes que pode usar Vue. Options API é o "modo tradicional", e consiste en definir a lóxica dun compoñente usando un obxecto javascript con distintos métodos e atributos que cubren o ciclo de vida e funcionalidades do compoñente:

name
Este atributo indica o nome do compoñente.
data()
Este método define o estado reactivo local do compoñente. Retorna un obxecto coas propiedades que desexamos sexan empregados no procesamento da plantilla de xeito reactivo.
created()
Este método se executa cando o compoñente é creado.
mounted()
Este método se executa cando o compoñente é montado no DOM.
updated()
Este método se executa cada vez que é necesario actualizar a plantilla.
destroyed()
Este método se executa cada vez que o compoñente se elimina.
provide() / inject
O método provide() permite compartir datos entre compoñentes "pais" e "fillos". provide() Debe retornar un obxecto onde se especifique como atributos a información a compartir. Esta información pode ser accedida polos fillos mediante o atributo inject, que indicará nun array o conxunto de datos "provided" a utilizar.
props
Este atributo especifica os datos (parámetros) que pode recibir o compoñente cando é "incluído" na web.
computed
Este atributo almacena un obxecto que contén métodos que podemos especificar como atributos na plantilla, deste xeito podemos eliminar a lóxica da plantilla deixandoa máis limpa e fácil de manter.
methods
Este atributo almacena un obxecto que contén métodos que podemos chamar dende a plantilla, principalmente como xestores de eventos. Si queremos, podemos usar para o método o mesmo identificador que o atributo que queremos "recalcular", de xeito que se refrescará cando o valor do atributo cambie.
watch
Este atributo almacena un obxecto que contén métodos que "observan" certas propiedades, executando un método cando se produce un cambio. Debemos identificar o método co mesmo nome que o atributo que queremos vixiar, e recibirá como parámetros o valor futuro e o valor actual.
components
Este atributo almacena un obxecto que contén compoñentes dos que queremos poder facer uso no compoñente actual.
mixins
Este atributo é un array que permite reutilizar funcionalidade para que sexa utilizada en varios compoñentes. Permiten compartir métodos, datos e ciclo de vida entre diferentes compoñentes. En primeiro lugar, se debe crar o "mixin" que consistirá nunha variable que almacene un obxecto coa información a reutilizar. Esa información se poderá utilizar en novos compoñentes especificando os mixin desexados no seu atributo mixins.
directives
Este atributo almacena obxectos que almacena métodos a aplicar a elementos concretos do DOM en unha frase concreta do ciclo de vida do compoñente (hooks). Os elementos que especifiquen v-[metodo] executarán a directiva no hook indicado que pode ser created,beforeMount,mounted,beforeUpdate,updated,beforeUmount e unmounted".
extends
Este atributo permite especificar un compoñente base do que se herdan as funcionalidades. E similar aos mixin, pero indicando un único compoñente.
inheritAttrs
Este atributo booleano controla a herdanza dos atributos. Por defecto os atributos especificados nun compoñente incluído que non son declarados como propiedades, se inclúen como atributos no elemento raíz do template, engadíndose as existentes si é o caso. Especificando false evitamos este comportamento, pero serán accesibles co prefixo "$" {{ $attr }}
emits
Este atributo é un array que conten un conxunto de métodos que "poden ser emitidos" mediante this.$emit. Este evento pode ser capturado co atributo @evento na chamada ao compoñente.
template
Este atributo almacena a plantilla a ser transformada en HTML e incrustada no DOM. Tamén pode indicarse fora do script entre <template> e </template>. A template define o documento a ser incrustado no DOM unha vez procesado coa información producida pola sección <script> e aplicando o estilo especificado na sección <style>. A reactividade garante que si os datos cambian, o template é procesado de novo para xerar unha nova saida.

Composition API

Coa Composition API utilízamos normalmente <script setup> para indicar o JavaScript a utilizar na inicialización do componente. Outra posibilidade é especificar un método setup() co mesmo código. Si queremos que o compoñente poda recibir parámtros, os debemos especificar mediante o atributo props, que conten un obxecto que indica todos os atributos que se poden recibir cando se chama ao compoñente. Todos os parámetros declarados en props son reactivos. En esta API podemos seleccionar que outros datos queremos que sexan reactivos de modo específico mediante os métodosref ou reactive (en options API, os datos se teñen que declarar en data() e sempre son reactivos).

ref é axeitado para datos simples, mentres que reactive é máis axeitado para obxectos complexos, que podan ter outros obxectos como atributos que tamén queremos que sexan reactivos. Cando definimos un dato como reactivo mediante o método ref necesitaremos usar o atributo .value para acceder ao seu valor. Outra posibilidade é shallowRef (que simplemente comproba si cambia a referencia do obxecto, en lugar do obxecto en sí).

Nos compoñentes con compositionAPI podemos definir as funcionalidades desexadas mediante métodos javascript. Estas funcionalidades simplemente variarán valores reactivos que provocan o repintado e polo tanto o "recálculo" da plantilla. Todo o código irá dentro do método setup(), ou si queremos unha sintaxe mais simple, dentro de <script setup>

Vexamos un exemplo de compoñente:

<script setup>
import { ref, onMounted } from 'vue'

// reactive state
const count = ref(0)

// functions that mutate state and trigger updates
function increment() {
  count.value++
}

// lifecycle hooks
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

<style scoped>
button {
  font-weight: bold;
}
</style>

Os hook da composition API son maiores que en Options API: setup(), onMounted(), onUpdated(), onUnmounted(), onBeforeMount(), onBeforeUpdate(), onBeforeUnmount, onErrorCaptured, onActivated, onDeactivated(),

Ambos os estilos de API son plenamente capaces de cubrir casos de uso comúns. Son interfaces diferentes impulsadas polo mesmo sistema subxacente. De feito, a Options API está implementada sobre a Composition API. Os conceptos fundamentais e o coñecemento sobre Vue son compartidos entre os dous estilos.

Se es novo en Vue, aquí está a nosa recomendación xeral:

Para fins de aprendizaxe, escolla o estilo que lle pareza máis fácil de entender. De novo, a maioría dos conceptos básicos son compartidos entre os dous estilos. Sempre podes aprender o outro estilo máis adiante.

Para uso en produción:

  • Escolla a Options API se non está a usar ferramentas de construción, ou se planea usar Vue principalmente en escenarios de baixa complexidade, por exemplo, mellora progresiva.
  • Escolla a Composition API + Compoñentes de Ficheiro Único se planea construir aplicacións completas con Vue.

Neste documento utilizaremos principalmente Composition API.

Comezando con plantillas en Vue

Vue utiliza unha sintaxe de templates baseada en HTML que che permite ligar de forma declarativa o DOM renderizado cos datos subxacentes da instancia do compoñente. Todos os templates de Vue son sintacticamente HTML válido, que pode ser analizado por navegadores compatibles co estándar e parsers de HTML.

Por debaixo, Vue compila os templates en código JavaScript altamente optimizado. Combinado co sistema de reactividade, Vue pode determinar de maneira intelixente o número mínimo de compoñentes que precisa volver renderizar e aplicar a mínima cantidade de manipulacións no DOM cando cambia o estado da aplicación.

As plantillas Vue se definen nos compoñentes dentro das etiquetas <template>...</template> e dispoñen dunha linguaxe de procesado de plantillas bastante simple e potente que procesará a información procesada na sección <script>:

Interpolación de Texto

A forma máis básica de vinculación de datos é a interpolación de texto utilizando a sintaxe de "mostacho" (dobres chaves):

<template>
  <span>Message: {{ msg }}</span>
</template>

A etiqueta de mostacho será substituída polo valor da propiedade `msg` da instancia do componente correspondente. Ademais, actualizarase cada vez que a propiedade `msg` cambie.

Vinculación de Atributos

As chaves non se poden usar dentro dos atributos HTML. En vez diso, usa a directiva `v-bind`:

<template>
  <div v-bind:id="dynamicId"></div>
</template>

A directiva `v-bind` indica a Vue que mantén o atributo id do elemento sincronizado coa propiedade `dynamicId` do compoñente. Se o valor vinculado é `null` ou `undefined`, o atributo será eliminado do elemento renderizado.

Sintaxe Abreviada Como `v-bind` se usa con moita frecuencia, ten unha sintaxe abreviada dedicada:

<template>
  <div :id="dynamicId"></div>
</template>

HTML Crudo

As dobres chaves interpretan os datos como texto sin formato, non como HTML. Para saír HTML real, necesitas usar a directiva `v-html`:

<template>
  <p>Usando interpolación de texto: {{ rawHtml }}</p>
  <p>Usando a directiva v-html: <span v-html="rawHtml"></span></p>
</template>

Atributos Booleanos

Os atributos booleanos son atributos que poden indicar valores verdadeiros/falsos pola súa presenza nun elemento. Por exemplo, `disabled` é un dos atributos booleanos máis comúns.

`v-bind` funciona dun xeito algo diferente neste caso:

<template>
  <button :disabled="isButtonDisabled">Button</button>
</template>

O atributo `disabled` incluirase se `isButtonDisabled` ten un valor verdadeiro. Tamén se incluirá se o valor é unha cadea de texto vacía, mantendo a coherencia con `<button disabled="">`. Para outros valores falsos, o atributo será omxido.

Vinculación dinámica de múltiples atributos

Se tes un obxecto de JavaScript que representa múltiples atributos e que ten a seguinte estrutura:

const objectOfAttrs = {
  id: 'container',
  class: 'wrapper',
  style: 'background-color:green'
}

Podes vinculalos a un único elemento utilizando `v-bind` sen un argumento:

<div v-bind="objectOfAttrs"></div>

Usando expresións de JavaScript

Até agora, só vinculamos claves de propiedades sinxelas nas nosas plantillas. Pero Vue realmente admite toda a potencia das expresións de JavaScript dentro de todas as vinculaciones de datos:

{{ number + 1 }}

{{ ok ? 'SÍ' : 'NON' }}

{{ message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>

Estas expresións serán avaliadas como JavaScript no ámbito de datos da actual instancia do componente. As comiñas invertidas ` na última expresión, permiten incluir variables para crear un texto pechadas con ${}.

Nas plantillas de Vue, as expresións de JavaScript pódense usar nas seguintes posicións:

- Dentro das interpolacións de texto (mustaches)
- No valor dos atributos de calquera directiva de Vue (atributos especiais que comezan con `v-`)

Chamando funcións

É posible chamar a un método exposto por un componente dentro dunha expresión de vinculación:

<time :title="toTitleDate(date)" :datetime="date">
  {{ formatDate(date) }}
</time>
  1. :title="toTitleDate(date)": O atributo title establécese de forma dinámica mediante v-bind, utilizando a sintaxe abreviada :. Isto indica que title tomará o seu valor do resultado da chamada ao método toTitleDate(date).
    • toTitleDate(date): Este método debería estar definido no compoñente, ben na sección methods (en Options API) ou directamente na función setup (en Composition API). A súa finalidade é formatear a data (date) nunha cadea que será usada como valor do atributo title. Por exemplo, toTitleDate podería devolver algo como "20 de Outubro de 2024" para amosar unha data legible cando o usuario poña o cursor enriba do tempo.
  2. :datetime="date": Aquí tamén se usa v-bind para ligar o valor do atributo datetime a unha variable date. Isto fai que datetime reciba directamente o valor de date. O atributo datetime en etiquetas
  3. {{ formatDate(date) }}: O contido dentro da etiqueta

As funcións chamadas dentro das expresións de vinculación serán executadas cada vez que o componente se actualice, polo que non deben ter efectos secundarios, como cambiar datos ou acender operacións asincrónicas. As expresións de plantilla están illadas e só teñen acceso a unha lista restrinxida de globais. A lista expón globais incorporados de uso común como Math e Date.

Directivas

As directivas son atributos especiais co prefijo `v-`. Vue proporciona unha serie de directivas incorporadas, incluíndo `v-html` e `v-bind.

Os valores dos atributos das directivas esperan ser expresións de JavaScript únicas (con excepción de `v-for`, `v-on` e `v-slot`). O traballo dunha directiva é aplicar actualizacións de forma reactiva no DOM cando o valor da súa expresión cambia. Tomemos como exemplo `v-if`:

<p v-if="seen">Agora me ves</p>

Neste caso, a directiva `v-if` eliminaría ou inseriría o elemento <p> en función da veracidade do valor da expresión lóxica seen. Outras directivas son:

  • v-on: Para xestionar eventos de usuario
  • v-for: Para procesar listas de datos de xeito repetitivo (producindo grupos de elementos HTML na plantilla)
  • v-slot: Para pasar contido de plantilla dende o pai ao fillo

v-on

A directiva v-on úsase para xestionar eventos de usuario, como pulsar un botón ou escribir nun campo de texto, e permite executar métodos específicos ao detectar eses eventos. Pódese abreviar usando @.

<button v-on:click="saudar">Prema aquí</button>

Isto asocia o evento click co método saludar, que debería estar definido no compoñente na seccion <script setup>.

<button @click="saludar">Prema aquí</button>
<button @click="incrementar(5)">Incrementar</button>
Prevención de comportamento por defecto
Para evitar o comportamento por defecto dun evento (como o envío dun formulario), úsase o modificador .prevent na plantilla HTML: <form @submit.prevent="procesarFormulario">...</form>. Outros modificadores posibles para usar na xestión de eventos na plantila son:
  • .stop:Evita a propagación do evento a través dos elementos pai.
  • .self:Unicamente atende a eventos producidos no propio elemento, sin facer caso a os elementos fillos
  • .capture:Indica que os eventos de este tipo producidos nos elementos interiores son xestionados por este método.
  • .once: Soamente se permite o evento unha vez.
  • .passive: Indica que se procesará o evento nativamente sen esperar a que se execute o xestor indicado

Os eventos de teclado, de xeito similar poden levar .enter, .page-dowwn, .tab, .delete, .esc, .space, .up, .down, .left, .right,.ctrl,.alt,.shift,.meta identificando a tecla pulsada e os de rato .left, right ou .middle identificando o botón pulsado.

v-for

A directiva v-for é empregada para renderizar listas e repetir un compoñente ou elemento en función dunha colección de datos, como un array. Require que se especifique un key único en cada elemento renderizado.

<ul>
   <li v-for="elemento in lista" :key="elemento.id">{{ elemento.nome }}</li> 
</ul>

Neste caso, lista debería ser unha colección de obxectos definida no compoñente en <script setup>, e cada elemento sería renderizado cun valor de id único. Tamén se pode usar o índice da colección de elementos:

<ul>
   <li v-for="(elemento, índice) in lista" :key="índice"> {{ índice }} - {{ elemento.nome }} </li> 
</ul>


Ou utilizar obxectos e as súas propiedades:

<ul>
   <li v-for="(valor, chave) in obxecto" :key="chave">{{ chave }}: {{ valor }}</li> 
</ul>

v-slot

A directiva v-slot permite crear e pasar contidos personalizados a compoñentes fillo desde o pai, mellorando a modularidade ao permitir especificar diferentes partes do contido dende o compoñente pai.

<template>
   <div> <slot></slot> </div> 
</template>

Usalo dende o compoñente pai: MeuCompoñente na sección <template>

<MeuCompoñente>
<p>Este parágrafo será amosado dentro do slot do compoñente.</p> 
</MeuCompoñente>
Os slots con nome permiten crear varios slots con nomes específicos
<template>
    <header> 
       <slot name="cabeceira"></slot> 
    </header> 
    <main> 
        <slot></slot> 
    </main> 
    <footer> 
       <slot name="pé"></slot> 
    </footer> 
</template>

Que se utilizaría do seguinte xeito:

   <MeuCompoñente> 
        <template v-slot:cabeceira> <h1>Cabeceira personalizada</h1> </template>
        <p>Este é o contido principal.</p> 
        <template v-slot:pé> <p>Pé de páxina personalizado</p> </template> 
   </MeuCompoñente>

Isto produciría un HTML co contido definido insertado nos slots correspondentes en MeuCompoñente.

Tamén é posible pasar e utilizar datos cos slots:

    <template> 
        <slot :datos="datosExemplo"></slot> 
    </template>

Que poderíamos utilizar así:

     <MeuCompoñente v-slot="{ datos }">
        <p>Os datos pasados son: {{ datos }}</p> 
     </MeuCompoñente>

Facendo consultas ao servidor: Axios

Aquí tes un breve titorial en galego normativo sobre o uso de Axios, unha libraría popular en JavaScript para realizar solicitudes HTTP de forma sinxela e eficiente:

Instalación de Axios Para comezar a usar Axios nun proxecto, primeiro debes instalalo. Se estás usando npm, executa o seguinte comando no terminal:

bash Copiar código npm install axios Para proxectos que usan Vue ou React, Axios intégrase facilmente e non require configuración adicional.

Realizar unha Solicitude GET Unha das funcións máis básicas de Axios é a solicitude GET, que permite obter datos dun servidor. Por exemplo, se queremos obter unha lista de usuarios dun endpoint, podemos facelo do seguinte xeito:

javascript Copiar código import axios from 'axios';

axios.get('https://api.exemplo.com/usuarios')

   .then(response => {
       console.log(response.data);
   })
   .catch(error => {
       console.error('Erro ao obter os usuarios:', error);
   });

Neste exemplo:

axios.get() envía unha solicitude GET á URL especificada. .then() xestiona a resposta cando a solicitude é exitosa. .catch() xestiona os erros se a solicitude falla. Realizar unha Solicitude POST Para enviar datos ao servidor, usamos a solicitude POST. Por exemplo, para crear un novo usuario:

javascript Copiar código axios.post('https://api.exemplo.com/usuarios', {

   nome: 'Xoán',
   correo: 'xoan@exemplo.com'

}) .then(response => {

   console.log('Usuario creado:', response.data);

}) .catch(error => {

   console.error('Erro ao crear usuario:', error);

}); Aquí, enviamos un obxecto JSON con información do usuario que queremos crear.

Configuración de Parámetros e Cabeceiras Para configurar parámetros ou cabeceiras adicionais, engádeos como terceiro argumento en axios.get() ou axios.post():

javascript Copiar código axios.get('https://api.exemplo.com/usuarios', {

   params: { id: 123 },
   headers: { 'Authorization': 'Bearer token' }

}) .then(response => {

   console.log(response.data);

}) .catch(error => {

   console.error('Erro:', error);

}); Uso de Interceptores Os interceptores permiten interceptar solicitudes ou respostas antes de que se procesen. Útil para engadir autenticación ou xestionar erros de forma global:

javascript Copiar código axios.interceptors.request.use(config => {

   config.headers['Authorization'] = 'Bearer token';
   return config;

}, error => {

   return Promise.reject(error);

});

axios.interceptors.response.use(response => {

   return response;

}, error => {

   console.error('Erro na resposta:', error);
   return Promise.reject(error);

}); Resumo das Funcións Básicas de Axios axios.get(url, config): Solicitude GET. axios.post(url, data, config): Solicitude POST. axios.put(url, data, config): Solicitude PUT para actualizar recursos. axios.delete(url, config): Solicitude DELETE para eliminar recursos.