de Ondřej Polesný

Cum să generați un site static cu Vue.js în cel mai scurt timp

Cum se genereaza un site static cu Vuejs in cel

Ați decis să construiți un site static, dar de unde începeți? Cum selectați instrumentul potrivit pentru job fără experiență anterioară? Cum vă puteți asigura că reușiți prima dată, evitând în același timp instrumentele care nu vă vor ajuta în cele din urmă?

În acest articol, veți afla cum să reglați un site Web Vue.js pentru a fi generat automat ca site static.

Introducere

Am rezumat diferențele cheie dintre un site web bazat pe API și site-urile statice articolul anterior. Ca un memento rapid, site-urile statice sunt:

  • Flăcând rapid
  • Sigur (deoarece sunt doar un set de pagini statice)
  • S-a regenerat de fiecare dată când editorii actualizează conținutul
  • Compatibil cu funcționalități dinamice suplimentare

Ce este un generator de site static?

Un generator de site static este un instrument care generează un site web static din implementarea și conținutul unui site web.

Conținutul poate proveni dintr-un sistem de gestionare a conținutului fără cap, printr-un API REST. Implementarea site-ului web utilizează unul dintre cadrele JavaScript, cum ar fi Vue.js sau React. Ieșirea unui generator de site static este un set de fișiere statice care formează site-ul web.

1611550512 698 Cum se genereaza un site static cu Vuejs in cel

Implementarea site-ului static

Am ales Vue.js ca cadrul JavaScript de utilizat. Prin urmare, voi lucra cu Nuxt.js, care este un generator de site static pentru Vue.js.

Dacă utilizați un cadru diferit, căutați un generator de site static construit deasupra cadrului respectiv (de exemplu Gatsby pentru React.js).

În esență, Nuxt este o combinație de instrumente multiple care împreună vă permit să creați site-uri statice. Instrumentele includ:

  • Vue2 – Biblioteca Core Vue.js.
  • Vue Router – Manevrează rutare URL pentru pagini de pe site.
  • Vuex – Magazin de memorie pentru datele partajate de componente.
  • Vue Server Renderer – Permite redarea paginilor de pe server înainte de generarea reală a fișierelor statice
  • Vue-Meta – Gestionează informațiile despre metadatele paginii

Nuxt definește, de asemenea, modul în care site-ul web trebuie construit pentru a genera fișiere statice.

Instalare

Pentru a începe să construiți site-uri web cu Nuxt, trebuie să îl instalați. Consultați instrucțiunile detaliate de instalare de pe Pagina web Nuxt.js. Pe scurt, ai nevoie npx (livrat implicit cu NPM) instalat și rulat:

npx create-nuxt-app <website-name>

Puteți folosi doar selecțiile implicite, cu excepția cazului în care aveți preferințe altfel.

Componente

În unul dintre articolele mele anterioare Am explicat cum să creați un aspect de șablon și componente. Toate acestea au fost definite într-un singur fișier components.js. Acest lucru trebuie schimbat cu Nuxt. Toate componentele trebuie extrase din components.js fișier în fișiere separate sub folder components. Uită-te la mine blog-list componentă și implementarea sa anterioară:

Vue.component('blog-list', { props: ['limit'], data: function(){  return {   articles: null  } },
 created: function(){  var query = deliveryClient   .items()   .type('blog_post')   .elementsParameter(['link', 'title', 'image_url', 'image', 'teaser'])   .orderParameter('elements.published', SortOrder.desc);   if (this.limit){   query = query.limitParameter(this.limit);  }  query   .getPromise()   .then(response =>    this.$data.articles = response.items.map(item => ({     url: item.link.value,     header: item.title.value,     image: item.image_url.value != '' ? item.image_url.value : item.image.assets[0].url,     teaser: item.teaser.value    }))   ); },
 template: `  <section class="features">   <article v-for="article in articles">    ...   </article>  </section> ` });

Pentru a o separa, trebuie să schimbați și sintaxa componentei pentru a se potrivi cu următorul șablon:

<template> HTML of the component</template><script> export default {  Vue.js code }</script>

Prin urmare, ajustarea mea Blog-list componenta arată astfel:

<template> <section class="features">  <article v-for="article in blogPosts">   ...  </article> </section></template><script> export default {  props: ['limit'],  computed: {   blogPosts: function(){    return this.$store.state.blogPosts && this.limit && this.$store.state.blogPosts.length > this.limit ? this.$store.state.blogPosts.slice(0, this.limit) : this.$store.state.blogPosts;   }  } }</script>

Vedeți că șablonul a rămas același. Ceea ce s-a schimbat este implementarea care este acum înăuntru export default secțiune. De asemenea, exista o funcție care aduna date din CMS Kentico Cloud fără cap.

Acest conținut este acum stocat în magazinul Vuex. Voi explica această parte mai târziu. Convertiți toate componentele dvs. în acest fel, pentru a conține șablon în interior <template> etichete și implementare within &lt; script> etichete. Ar trebui să sfârșiți cu o structură de fișiere similară cu cea pe care o am:

1611550512 933 Cum se genereaza un site static cu Vuejs in cel

Rețineți că am două componente noi aici – Meniu și Antet. Deoarece scopul meu era să îmbunătățesc și performanța, am decis să elimin jQuery de pe site-ul meu. jQuery este o bibliotecă destul de mare și grea, care a fost utilizată doar pentru efecte UI mici. Am putut să le recreez folosind doar Vue.js. Prin urmare, am convertit HTML-ul static care reprezintă antetul în componentă. Am adăugat, de asemenea, funcționalitatea legată de interfața de utilizare mounted funcția acestei componente.

mounted: function(){ window.addEventListener(‘scroll’, this.scroll); …},methods: { scroll: function(){  … }}

Gestionarea evenimentelor Vue.js cu Nuxt

Obișnuiam să folosesc evenimentele Vue de pe site-ul meu web. Motivul principal a fost controlul reCaptcha utilizat pentru validarea formularului. Când a fost inițializat, va transmite evenimentul, astfel încât componenta formularului să poată debloca butonul de trimitere al formularului de contact.

Cu Nuxt, nu mai folosesc app.js sau components.js fișiere. De aceea am creat un nou recaptcha.js fișier care conține o funcție simplă care emite evenimentul când reCaptcha se pregătește. Rețineți că, în loc să creați o nouă instanță Vue.js doar pentru evenimente (let bus = new Vue(); în vechiul meu cod), este posibil să se utilizeze pur și simplu this.$nuxt la fel.

var recaptchaLoaded = function(){ this.$nuxt.$emit('recaptchaLoaded');}

Aspect și pagini

Cadrul principal al paginii era index.html, și fiecare pagină și-a definit propriul aspect în constante care au fost predate routerului Vue.

Cu Nuxt, cadrul principal, inclusiv <html> tag, metaetichetele și alte elemente esențiale ale oricărei pagini HTML sunt gestionate de Nuxt. Implementarea efectivă a site-ului web gestionează numai conținut within etichete . Mutați aspectul obișnuit pentru toți pages into layouts/default.vue și respectați același șablon ca și în cazul componentelor. Aspectul meu arată astfel:

<template> <div>  <Menu></Menu>  <div id="page-wrapper">   <Header></Header>   <nuxt/>   <section id="footer">    <div class="inner">     …     <ContactForm></ContactForm>     …    </div>   </section>  </div> </div></template><script> import ContactForm from ‘~/components/Contact-form.vue’ import Menu from ‘~/components/Menu.vue’ import Header from ‘~/components/Header.vue’  export default {  components: {   ContactForm,   Menu,   Header  } } </script>

Aspectul este practic marcajul HTML al vechiului meu index.html. Cu toate acestea, rețineți <script> sectiune. Toate componentele pe care vreau să le folosesc în acest șablon de aspect trebuie să fie importate din locația lor și specificate în obiectul exportat.

1611550512 813 Cum se genereaza un site static cu Vuejs in cel

Componentele paginii au fost definite anterior în app.js ca constante. Aruncați o privire la vechea mea pagină de pornire, de exemplu:

const Home = { template: `  <div>   <banner></banner>   <section id="wrapper">    <about-overview></about-overview>    ...    <blog-list limit="4"></blog-list>    <ul class="actions">     <li><a href="https://www.freecodecamp.org/blog" class="button">See all</a></li>    </ul>    ...   </section>  </div> `}

Toate aceste pagini trebuie definite în fișiere separate pages pliant. Pagina principală este întotdeauna apelată index.vue. Așa este noul meu pages/index.vue (Pagina mea de start) arată:

<template> <div>  <Banner></Banner>  <section id="wrapper">   <AboutOverview></AboutOverview>   ...   <BlogList limit="4"></BlogList>   <ul class="actions">    <li><a href="https://www.freecodecamp.org/blog" class="button">See all</a></li>   </ul>   ...  </section> </div></template><script> import Banner from ‘~/components/Banner.vue’ import AboutOverview from ‘~/components/About-overview.vue’ import BlogList from ‘~/components/Blog-list.vue’  export default {  components: {   Banner,   AboutOverview,   BlogList  }, }</script>

Unde se stochează activele

Pe fiecare site web există materiale precum foi de stil CSS, imagini, sigle și JavaScript. Cu Nuxt, toate aceste fișiere statice trebuie stocate în folderul static. Deci, structura de dosare arată în prezent astfel:

1611550512 233 Cum se genereaza un site static cu Vuejs in cel

Când faceți referire la orice resurse din foile de stil CSS, cum ar fi fonturile sau imaginile, trebuie să utilizați folderul static ca rădăcină:

background-image: url("~/assets/images/bg.jpg");

Obținerea de conținut

Cu toate componentele și paginile la locul lor, ajungem în cele din urmă la el: introducerea conținutului în componente.

Obținerea de conținut utilizând Nuxt este puțin diferită decât era. Aspectul important al acestui proces atunci când se utilizează un generator de site static este că conținutul trebuie colectat înainte ca toate paginile să fie generate. În caz contrar, veți ajunge la un site static, dar solicitările de conținut ar fi în continuare dinamice, lovind CMS fără cap din browserul fiecărui vizitator și veți pierde principalul beneficiu.

Nuxt conține două metode speciale care gestionează preluarea asincronă a datelor la momentul potrivit, adică înainte de generarea paginilor. Aceste metode sunt asyncData și fetch. Acestea sunt disponibile numai pentru componentele paginii (adică fișierele din pages folder) și scopul lor este același, dar asyncData va stoca automat datele primite în setul de date al componentei.

Acest lucru poate fi benefic dacă aveți mai multe componente pe o singură pagină folosind același set de date. În cazul meu, am chiar mai multe pagini cu multe componente care trebuie să împărtășească aceleași date. Prin urmare, ar trebui fie să cer aceleași date pe fiecare pagină, fie să folosesc un spațiu partajat la care toate paginile și componentele ar putea accesa.

Eu l-am ales pe acesta din urmă. Nuxt ne este foarte ușor. Include automat magazin Vuex care permite accesul componentelor și paginilor noastre la orice date care se află în magazin. Pentru a începe să utilizați magazinul, tot ce trebuie să faceți este să creați un index.js fișier în cadrul store pliant.

import Vuex from 'vuex'
const createStore = () => { return new Vuex.Store({  state: () => ({}),  mutations: {},  actions: {}, })}export default createStore

Vedeți că instanța are câteva proprietăți:

  • Stat
    Starea este similară cu datele din componente. Conține definiția câmpurilor de date care sunt utilizate pentru stocarea datelor.
  • Mutații
    Mutația sunt funcții speciale care au permisiunea de a schimba datele în stat (mutarea stării).
  • Acțiuni
    Acțiunile sunt metode simple care vă permit, de exemplu, să implementați logica de colectare a conținutului.

Să revenim la Blog-list componentă. Această componentă are nevoie de o serie de postări de blog pentru a-și reda marcajul. Prin urmare, postările de blog trebuie stocate în magazinul Vuex:

…const createStore = () => { return new Vuex.Store({  state: () => ({   blogPosts: null  }),  mutations: {   setBlogPosts(state, blogPosts){    state.blogPosts = blogPosts;   }  },  actions: {   getBlogPosts (context) {    logic to get content from Kentico Cloud   }  }, })}

După ce ați ajustat magazinul Vuex în acest fel, Blog-list componenta poate folosi datele sale:

<article v-for="article in $store.state.blogPosts"> …</article>

Am împărtășit deja întreaga implementare a acestei componente de mai sus. Dacă ați observat, se folosește computed funcționează ca un strat de mijloc între marcarea componentelor și magazinul Vuex. Stratul de mijloc asigură faptul că componenta afișează doar o anumită cantitate de articole așa cum este configurat în limit camp.

Interogarea CMS fără cap

Poate îți amintești deliveryClient a fost folosit pentru a obține date de la Norul Kentico în componente.

Declinare de responsabilitate: Lucrez pentru Kentico, un furnizor de CMS care oferă atât CMS tradițional (cuplat), cât și un nou CMS fără cap – Cloud Kentico.

Aceeași logică poate fi utilizată aici în acțiunile magazinului Vuex cu o mică modificare. Kentico Cloud are o modul pentru Nuxt.js, instalați-l folosind următoarea comandă:

npm i kenticocloud-nuxt-module — savenpm i rxjs — save

Cu acest modul puteți continua să utilizați deliveryClient ca înainte, doar cu un $ prefix. Deci, în cazul meu, logica pentru a obține postări pe blog arată astfel:

…getBlogPosts (context) { return this.$deliveryClient  .items()  ...  .orderParameter('elements.published', SortOrder.desc)  .getPromise()  .then(response => {   context.commit('setBlogPosts', response.items.map(item => ({    url: item.link.value,    header: item.title.value,    image: item.image_url.value != '' ? item.image_url.value : item.image.assets[0].url,    teaser: item.teaser.value   })))  }); },…

Dacă doriți să utilizați comanda folosind orderParameter, poate fi necesar să includeți un alt import în store/index.js fişier:

import { SortOrder } from 'kentico-cloud-delivery'

Acum, când este implementată logica de colectare a conținutului, este timpul să folosiți funcția de preluare a funcției asincrone speciale pe care am menționat-o mai înainte. Vedeți implementarea mea în index.vue pagină:

async fetch ({store, params}) { await store.dispatch('getBlogPosts')}

Apelul la store.dispatch invocă automat getBlogPosts acțiune. În cadrul getBlogPosts punerea în aplicare notează apelul pentru context.commit. context se referă la magazinul Vuex și commit va preda datele postărilor de blog către setBlogPosts mutaţie. Actualizarea setului de date cu postări pe blog modifică starea magazinului (îl mută). Și aproape am terminat!

Alte opțiuni de stocare a conținutului

obisnuiam Norul Kentico CMS fără cap și API-ul său aici, deoarece îl folosesc în toate articolele din această serie. Dacă doriți să verificați și alte opțiuni, puteți găsi o listă independentă de CMS-uri fără cap și caracteristicile acestora la headlesscms.org.

Dacă nu doriți să utilizați un CMS fără cap și API-ul acestuia, puteți decide să vă stocați conținutul într-un alt mod – de obicei ca un set de fișiere de reducere stocate direct în proiectul dvs. sau în depozitul Git. Puteți găsi un exemplu frumos al acestei abordări în nuxt-markdown-exemplu depozit GitHub.

Configurare Nuxt

Întreaga aplicație trebuie să fie configurată corect folosind Nuxt.config.js fişier. Acest fișier conține informații despre modulele utilizate, configurarea acestora și elementele esențiale ale site-ului, cum ar fi titlul sau etichetele SEO. Configurarea site-ului meu web arată astfel:

export default { head: {  title: 'Ondrej Polesny',  meta: [   { charset: 'utf-8' },   ...   { hid: 'description', name: 'description', content: 'Ondrej Polesny — Developer Evangelist + dog lover + freelance bus driver' }  ],  script: [   { src: 'https://www.google.com/recaptcha/api.js?onload=recaptchaLoaded', type: "text/javascript" },   { src: 'assets/js/recaptcha.js', type: "text/javascript" }  ], }, modules: [  'kenticocloud-nuxt-module' ], kenticocloud: {  projectId: '*KenticoCloud projectId*',  enableAdvancedLogging: false,  previewApiKey: '' }, css: [  {src: 'static/assets/css/main.css'}, ], build: {  extractCSS: {   allChunks: true  } }}

Secțiunea principală descrie elementele esențiale ale site-ului web, cum ar fi title și meta etichetele pe care doriți să le includeți în antet.

Rețineți modules și kenticocloud configurare. Primul listează toate modulele de care depinde aplicația dvs., iar al doilea este configurarea specifică a modulului. Acesta este locul în care trebuie să puneți cheia API a proiectului.

Pentru a vedea toate opțiunile pentru metaetichete, vă rugăm să consultați https://github.com/declandewet/vue-meta

Rularea și generarea

Site-urile statice trebuie generate înainte ca oricine să le poată accesa sau încărca pe un server FTP. Cu toate acestea, ar fi foarte mult timp să regenerăm site-ul de fiecare dată când s-a făcut o modificare în timpul fazei de dezvoltare. Prin urmare, puteți rula aplicația local folosind:

npm run dev

Acest lucru vă va crea un server de dezvoltare și vă va permite să accesați site-ul dvs. web pe http: // localhost: 8000 (sau similar). În timp ce consola dvs. rula această comandă, fiecare modificare pe care o faceți în scripturi va avea efect imediat pe site.

Pentru a genera un site static adevărat, executați următoarea comandă:

npx nuxt generate

Ieșirea, care este site-ul dvs. static, va fi în dist pliant. Simțiți-vă liber să deschideți orice pagină din editorul dvs. de text preferat și să vedeți dacă codul sursă conține conținut din CMS fără cap. Dacă da, a fost preluat cu succes.

Concluzie

A avea un site static generat va îmbunătăți foarte mult performanța site-ului. În comparație cu site-urile tradiționale, serverul web nu are nevoie să efectueze nicio operație grea a procesorului. Acesta servește numai fișiere statice.

În comparație cu site-urile web bazate pe API, clienții primesc datele solicitate instantaneu cu primul răspuns. Iată ce le face atât de rapide – nu trebuie să aștepte livrarea conținutului extern prin cereri suplimentare asincrone. Conținutul este deja acolo în primul răspuns de la server. Aceasta îmbunătățește dramatic experiența utilizatorului.

Conversia site-ului din implementarea Vue.js în definițiile Nuxt este foarte simplă și nu necesită cunoștințe profunde despre toate componentele și pachetele utilizate.

Ați creat cu succes primul dvs. site static? Ați trăit vreo luptă? Vă rugăm să lăsați un comentariu.

În articolul următor mă voi concentra pe regenerarea automată a site-urilor statice și unde să le găzduiesc, așa că rămâneți la curent.

  1. Cum să începeți să creați un site web impresionant pentru prima dată
  2. Cum să decideți cea mai bună tehnologie pentru site-ul dvs. web?
  3. Cum să vă alimentați site-ul web cu Vue.js și un efort minim
  4. Cum se amestecă CMS fără cap cu un site Vue.js și Pay Zero
  5. Cum să faceți trimiterile de formulare sigure pe un site web API
  6. Construirea unui site web rapid și sigur cu un CMS nu este o mare problemă. Sau este?
  7. Cum să generați un site static cu Vue.js în cel mai scurt timp
  8. Cum să configurați rapid un proces de compilare pentru un site static