Vue: Single File Components
Con Vue podemos crear componentes de múltiples formas, la más sencilla es cómo vismo en un post anterior donde utilizamos el método Vue.component().
Sin embargo esa forma, aunque es la más sencilla y práctica, no es la más escalable, ya que nos obliga a escribir el HTML dentro del método Vue.component() o a utilizar múltiples <templates> en el HTML.
¿Qué es un Single File Component?
Para solventar esto, existe una solución que junto con Webpack y un módulo (vue-loader) nos permite tener en un único fichero la vista (template), el diseño (css) y la lógica (javascript). Estos ficheros tienen una extensión .vue y tienen la siguiente forma:
<template>
<!-- Marcado HTML -->
</template>
<script>
/* Código JavaScript */
</script>
<style>
/* Estilos CSS */
</style>
Versatilidad con preprocesadores y lenguajes alternativos
Lo bueno de éste fichero, es que al no ser un fichero final de producción, es un fichero de desarrollo que luego Webpack interpreta y extrae las diferentes partes a sus ficheros correspondientes, nos da mucha versatilidad, por ejemplo:
Si preferimos utilizar Pug/Jade para el marcado en lugar de HTML convencional, podemos hacerlo porque Webpack leerá el fichero y gracias a los "loaders" transpilará el código al resultado final.
De igual manera, si prefieres utilizar TypeScript o CoffeeScript para el código JavaScript, también es posible, al igual que el estilo, puedes utilizar cualquier preprocesador que quieras: Less, Stylus, Sass, SCSS, PostCSS,...
Lo único que tienes que hacer es indicar en cada tag que tipo estás utilizando con el atributo lang. Por ejemplo:
<template lang="pug"> ... </template>
<script lang="ts"></script>
<style lang="scss"></style>
Esto lo hace muy versátil y práctico para equipos de trabajo dónde haya personas dedicadas al diseño y maquetación, y otras personas encargadas del código. De esta manera, la persona dedicada al CSS puede utilizar el preprocesador que prefiera, el desarrollador utilizar TypeScript si lo prefiere, etc...
Convirtiendo un componente a Single File Component
Entonces para este ejemplo vamos a tomar el componente que hicimos en el anterior post, que tenía esta pinta:
Vue.component("movie-card", {
props: ["image", "title"],
template: `
<div>
<img width="100" v-bind:src="image" v-bind:alt="title"/>
<h2>{{ title }}</h2>
</div>
`,
});
Y lo traducimos a un Vue Single File Component:
<template>
<div>
<img width="100" v-bind:src="image" v-bind:alt="title" />
<h2>{{ title }}</h2>
</div>
</template>
<script>
export default {
name: "movie-card",
props: {
image: String,
title: String,
},
};
</script>
<style scoped>
h2 {
font-size: 18pt;
}
</style>
La sección script
En la parte <script> utilizamos sintáxis de ES6, ya que con Webpack y Babel se realizará el transpiling aunque el navegador ya empieza a implementar éstas novedades.
Exporta por defecto un objeto JavaScript que contiene varias propiedades. En este ejemplo le indicamos con name que el compon