diff --git a/assets/css/main.css b/assets/css/main.css index d8a6c03..4c1e1d7 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1,3 +1,4 @@ @import url('./global.css'); @import url('./animations.css'); @import url('./variables.css'); +@import url('./posts.css'); diff --git a/assets/css/posts.css b/assets/css/posts.css new file mode 100644 index 0000000..682f9bb --- /dev/null +++ b/assets/css/posts.css @@ -0,0 +1,38 @@ +article > .nuxt-content h2 { + margin-top: 30px; + margin-bottom: 10px; + font-size: 1.125rem; + font-weight: bold; +} + +article > .nuxt-content .vue { + background-color: theme('colors.green-main.400'); + color: white; + padding: 0 3px; +} + +article > .nuxt-content .code { + background-color: theme('colors.blue-main.750'); + color: theme('colors.gray-main.950'); + padding: 0 3px; +} + +article > .nuxt-content a { + /* TODO: integrate tailwind */ + text-decoration: none; + color: #1f8ed5; + font-weight: bold; + opacity: 1; + border-bottom: solid 1px transparent; + -webkit-transition: opacity 0.2s ease-out, border-bottom-color 0.4s ease-out; + -moz-transition: opacity 0.2s ease-out, border-bottom-color 0.4s ease-out; + -ms-transition: opacity 0.2s ease-out, border-bottom-color 0.4s ease-out; + -o-transition: opacity 0.2s ease-out, border-bottom-color 0.4s ease-out; + transition: opacity 0.2s ease-out, border-bottom-color 0.4s ease-out; +} + +article > .nuxt-content a:hover { + /* TODO: integrate tailwind */ + opacity: 0.8; + border-bottom: solid 1px #1f8ed5; +} diff --git a/components/blog/CustomImage.vue b/components/blog/CustomImage.vue new file mode 100644 index 0000000..512d77c --- /dev/null +++ b/components/blog/CustomImage.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/components/ui/BlogCard.vue b/components/ui/BlogCard.vue index 4631c02..0365aa4 100644 --- a/components/ui/BlogCard.vue +++ b/components/ui/BlogCard.vue @@ -4,7 +4,7 @@ {{ title }}
- {{ getDate(date) }} + 🗓 {{ getDate(date) }} {{ getTimeToReadText(timeToRead) }} @@ -79,7 +79,7 @@ $mobile: var(--mobile); transition: box-shadow 0.5s ease, transform 0.5s ease; padding: 10px; - @apply flex flex-col cursor-pointer mb-4; + @apply flex flex-col cursor-pointer mb-4 border border-gray-main-300 rounded-md; } .post:hover { diff --git a/components/ui/CoffeeWidget.vue b/components/ui/CoffeeWidget.vue new file mode 100644 index 0000000..14123f5 --- /dev/null +++ b/components/ui/CoffeeWidget.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/content/blog/add-i18n-vue.md b/content/blog/add-i18n-vue.md new file mode 100644 index 0000000..721c762 --- /dev/null +++ b/content/blog/add-i18n-vue.md @@ -0,0 +1,10 @@ +--- +title: 'Añadir i18n en una aplicación Vue' +description: 'Cómo traducir tus aplicaciones con Vue e I18n' +date: 2019-02-01 +timeToRead: 5 +--- + +# Hello test 2 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam viverra tincidunt ligula in congue. Cras nec sapien a risus varius dictum. Sed rhoncus convallis sapien quis varius. In justo leo, congue et convallis sed, feugiat et orci. Quisque quam elit, venenatis non diam eget, hendrerit posuere ex. Nam condimentum elit aliquam nisl varius, quis luctus massa ullamcorper. Curabitur ac pellentesque arcu. Nulla turpis libero, condimentum vel tempor non, sagittis vitae sem. Etiam aliquet eu nisl vel dictum. Phasellus vitae ornare purus, ut euismod quam. In eget tristique lacus. Duis lectus sem, pretium sit amet mollis vitae, sagittis eu augue. diff --git a/content/blog/deploy-vue-app.md b/content/blog/deploy-vue-app.md new file mode 100644 index 0000000..035f113 --- /dev/null +++ b/content/blog/deploy-vue-app.md @@ -0,0 +1,10 @@ +--- +title: 'Desplegar una aplicación hecha con Vue en GithubPages' +description: 'Tutorial sobre cómo desplegar una aplicación Vue en github pages' +date: 2018-11-01 +timeToRead: 2 +--- + +# Hello test 2 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam viverra tincidunt ligula in congue. Cras nec sapien a risus varius dictum. Sed rhoncus convallis sapien quis varius. In justo leo, congue et convallis sed, feugiat et orci. Quisque quam elit, venenatis non diam eget, hendrerit posuere ex. Nam condimentum elit aliquam nisl varius, quis luctus massa ullamcorper. Curabitur ac pellentesque arcu. Nulla turpis libero, condimentum vel tempor non, sagittis vitae sem. Etiam aliquet eu nisl vel dictum. Phasellus vitae ornare purus, ut euismod quam. In eget tristique lacus. Duis lectus sem, pretium sit amet mollis vitae, sagittis eu augue. diff --git a/content/blog/event-bus.md b/content/blog/event-bus.md index 23d7c28..329cc6b 100644 --- a/content/blog/event-bus.md +++ b/content/blog/event-bus.md @@ -3,7 +3,6 @@ title: 'Bus de Eventos global con Vue' description: 'Ejemplo de bus de eventos en Vue' date: 2019-05-01 timeToRead: 3 -name: event-bus --- # Hello test 2 diff --git a/content/blog/scaffolding-vue.md b/content/blog/scaffolding-vue.md index e58bedf..200b6a9 100644 --- a/content/blog/scaffolding-vue.md +++ b/content/blog/scaffolding-vue.md @@ -3,9 +3,54 @@ title: 'Estructura de carpetas en Vue' description: 'Ejemplo de estructura de carpetas en Vue' date: 2020-02-01 timeToRead: 4 -name: scaffolding-vue --- -# Hello test +Hace ya un tiempo que empecé a trabajar con Vue y, sinceramente, es uno de los frameworks que más me apasiona. Entre muchas razones, me gusta por su sencillez, por su flexibilidad y por su comunidad. -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam viverra tincidunt ligula in congue. Cras nec sapien a risus varius dictum. Sed rhoncus convallis sapien quis varius. In justo leo, congue et convallis sed, feugiat et orci. Quisque quam elit, venenatis non diam eget, hendrerit posuere ex. Nam condimentum elit aliquam nisl varius, quis luctus massa ullamcorper. Curabitur ac pellentesque arcu. Nulla turpis libero, condimentum vel tempor non, sagittis vitae sem. Etiam aliquet eu nisl vel dictum. Phasellus vitae ornare purus, ut euismod quam. In eget tristique lacus. Duis lectus sem, pretium sit amet mollis vitae, sagittis eu augue. +Una vez comienzas a usar Vue con asiduidad y realizas varios proyectos, empiezas a darte cuenta de que su base se construye sobre componentes. Con el desarrollo de aplicaciones se hace notar su flexibilidad con respecto a la estructura de carpetas, el framework no te pone prácticamente ningún problema al respecto, pero una vez comienzas a generar vistas (que son componentes), componentes que pertenecen solo a una vista, componentes comunes, etc. ¿qué pasa? ¿cómo organizamos todos esos componentes para verlos día a día y que sea lo menos doloroso posible? + +En el post de hoy os enseñaré un ejemplo de scaffolding, el cual he ido adquiriendo con el paso del tiempo tras probar un ejemplo tras otro, finalmente este es, desde mi opinión, el más cómodo. + +## Crear estructura base + +Para empezar, tendremos que generar un proyecto de Vue básico con vue-cli, ya que la estructura que nos presenta desde un primer momento es la que intentaremos mantener siempre. Yo he generado un proyecto con la configuración lo más real posible a lo que se podría usar en un proyecto relativamente grande. + + + +Una vez termine de instalarse todo, esta será la estructura que nos genera vue-cli. + + + +## Crear componentes globales + +Cuando desarrollas una aplicación SPA, por ejemplo, con diferentes rutas y diferentes vistas, al final terminas teniendo componentes que se usan solamente en ciertas vistas y otros que se usan por toda la aplicación. En este apartado vamos a organizar los componentes comunes por tipos de componentes. Veamos un ejemplo visual: + + + +Como veis, dentro de la carpeta Components hemos generado dos carpetas, una Layout y otra Ui. Esto son dos de las diferenciaciones que yo suelo hacer en mis proyectos, pero depende del proyecto o del equipo de desarrollo los tipos de organización pueden variar. + +En el caso de tener componentes que no pertenecen a ningún tipo específico, la idea sería generar una carpeta llamada Common a la misma altura que layout y ui. + +## Crear componentes de vista + +Una vez que tengamos los componentes globales organizados, continuaremos con los componentes que solamente pertenecen a una vista en concreto. Veamos un ejemplo. + + + +En este ejemplo vemos como he creado una carpeta por vista y dentro de ella el componente de la vista lo he llamado index.vue. Dentro de cada carpeta existe una carpeta components que en este caso pertenecen solamente a los componentes de la vista. + +## Resto de ficheros + +Una vez tengamos los componentes organizados, vamos a organizar el resto de ficheros de la aplicación. La idea sería crear una carpeta shared dentro de nuestro src y ahí añadir por ejemplo nuestras constantes, los archivos de traducciones, directivas, mixins, constantes, modelos, etc. + + + +La idea de shared es mantener lo nativo de Vue en la carpeta raíz (components, store, etc.) y el contenido adicional almacenarlo dentro de este directorio. + +## Conclusión + +Por último, me gustaría remarcar que aunque para mi este scaffolding es el más útil para trabajar no tiene que ser así para todo el mundo. Así que os animo a todos a probar día a día cual es el que más se adapta a vuestra forma de trabajo. + +Espero que pueda serviros de ayuda y cualquier feedback por twitter será bienvenido ✌️. + +Os dejo también el link al repo de github, por si os queréis descargar este ejemplo. diff --git a/nuxt.config.js b/nuxt.config.js index 575c7e8..5de3b55 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -19,17 +19,24 @@ export default { content: process.env.npm_package_description || '', }, ], - link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }], + link: [ + { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }, + { + rel: 'stylesheet', + href: 'https://fonts.googleapis.com/css?family=Cookie', + }, + ], }, /* ** Global CSS */ css: ['~/assets/css/main.css'], + components: true, /* ** Plugins to load before mounting the App ** https://nuxtjs.org/guide/plugins */ - plugins: [], + plugins: ['~/plugins/global.js'], /* ** Nuxt.js dev-modules */ @@ -89,6 +96,22 @@ export default { langDir: 'locales/', vueI18n: { fallbackLocale: 'es', + dateTimeFormats: { + es: { + short: { + year: 'numeric', + month: 'long', + day: 'numeric', + }, + }, + en: { + short: { + year: 'numeric', + month: 'long', + day: 'numeric', + }, + }, + }, }, }, /* diff --git a/package-lock.json b/package-lock.json index 47fe9d8..2bd3519 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1172,9 +1172,9 @@ } }, "@nuxt/components": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@nuxt/components/-/components-1.0.3.tgz", - "integrity": "sha512-ZXnRHR4e+svOSaouWUoDCkXUHGC/8KGU5sU0SA/on0yHGuzsk/tD8vDiGYNGcdAxEAXE5J9xB7rzWcBYZMrOlg==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@nuxt/components/-/components-1.0.6.tgz", + "integrity": "sha512-ltXOL/ez3AMjluu3L+YI6hHwzJF+IQ5H2+ijUXPBswsDT/uSHZNe0PxnRrykj11IcpMqudQqBz713fakX7MvNg==", "requires": { "chalk": "^4.1.0", "chokidar": "^3.4.0", diff --git a/package.json b/package.json index a26ca8c..0d0fc2a 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ }, "dependencies": { "@fortawesome/free-solid-svg-icons": "^5.13.1", + "@nuxt/components": "^1.0.6", "@nuxt/content": "^1.3.2", "@nuxtjs/pwa": "^3.0.0-beta.20", "nuxt": "^2.13.0", diff --git a/pages/blog/_slug.vue b/pages/blog/_slug.vue index f34ad70..be4dd19 100644 --- a/pages/blog/_slug.vue +++ b/pages/blog/_slug.vue @@ -1,5 +1,15 @@ + + diff --git a/pages/blog/index.vue b/pages/blog/index.vue index 2a83c7d..cd4b673 100644 --- a/pages/blog/index.vue +++ b/pages/blog/index.vue @@ -6,7 +6,7 @@ v-for="(post, index) in posts" :key="index" v-bind="post" - @select="goToPost(post.name)" + @select="goToPost(post.path)" />
@@ -22,12 +22,12 @@ export default { BlogCard, }, async asyncData({ $content }) { - const posts = await $content('blog').fetch() + const posts = await $content('blog').sortBy('date', 'desc').fetch() return { posts } }, methods: { - goToPost(name) { - this.$router.push({ path: `/blog/${name}` }) + goToPost(path) { + this.$router.push({ path }) }, }, } diff --git a/plugins/global.js b/plugins/global.js new file mode 100644 index 0000000..b91be61 --- /dev/null +++ b/plugins/global.js @@ -0,0 +1,4 @@ +import Vue from 'vue' +import CustomImage from '@/components/blog/CustomImage.vue' + +Vue.component('custom-image', CustomImage) diff --git a/static/images/posts/scaffolding-vue/options-vue-cli.png b/static/images/posts/scaffolding-vue/options-vue-cli.png new file mode 100644 index 0000000..f271d0b Binary files /dev/null and b/static/images/posts/scaffolding-vue/options-vue-cli.png differ diff --git a/static/images/posts/scaffolding-vue/scaffolding-base.png b/static/images/posts/scaffolding-vue/scaffolding-base.png new file mode 100644 index 0000000..7028a44 Binary files /dev/null and b/static/images/posts/scaffolding-vue/scaffolding-base.png differ diff --git a/static/images/posts/scaffolding-vue/scaffolding-global-components.png b/static/images/posts/scaffolding-vue/scaffolding-global-components.png new file mode 100644 index 0000000..911f335 Binary files /dev/null and b/static/images/posts/scaffolding-vue/scaffolding-global-components.png differ diff --git a/static/images/posts/scaffolding-vue/scaffolding-rest-of-files.png b/static/images/posts/scaffolding-vue/scaffolding-rest-of-files.png new file mode 100644 index 0000000..499c7c8 Binary files /dev/null and b/static/images/posts/scaffolding-vue/scaffolding-rest-of-files.png differ diff --git a/static/images/posts/scaffolding-vue/scaffolding-views-components.png b/static/images/posts/scaffolding-vue/scaffolding-views-components.png new file mode 100644 index 0000000..5cb51a4 Binary files /dev/null and b/static/images/posts/scaffolding-vue/scaffolding-views-components.png differ diff --git a/tailwind.config.js b/tailwind.config.js index 4c9bdd4..7ae9c87 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -2,12 +2,18 @@ module.exports = { theme: { extend: { colors: { + 'green-main': { + 400: '#4fc08d', + }, 'gray-main': { + 300: '#e4e4e4', 700: '#808080', + 950: '#1a1a1a', }, 'blue-main': { 400: '#1f8ed5', 700: '#35495e', + 750: '#1f8ed540', 800: '#2c3e50', }, },