Vue.js je JavaScript okvir za izgradnju korisničkih sučelja (UI) i jednog od najpopularnijih okvira za razvoj web aplikacija. To je progresivni okvir koji se fokusira na deklarativno programiranje, jednostavnost upotrebe i brzinu razvoja.

Ukratko, Vue.js omogućuje razvoj dinamičkih web stranica i aplikacija, omogućujući programerima da lako povezuju podatke s korisničkim sučeljem i stvaraju interaktivne aplikacije. Vue.js je često korišten za izgradnju pojednostavljenih, modernih, i brzih web aplikacija.

Meni je potreban Vue zato što želim framework koji dobro funkcionira sa vanila JS-om, jquery-em i Bootstrap predlošcima. A stranice bih hostao na Firebase i sličnim povoljnim provajderima web prostora.

Znači ovo pišem iz perspektive nekoga tko primarno želi raditi web stranice a da mu je pritom potrebna brza integracija svega dostupnoga (jquery) u stranicu.

Instalacija

Za globalni pristup preko naredbenog retka:

sudo npm install -g @vue/cli

Ukoliko imamo problema s instalacijom poželjno je jednostavno izbrisati staru instalaciju:

sudo rm /usr/bin/vue

Stvaramo projekt:

vue create my-project

Izaberite “Manually select features”…

Sa space tipkom selektiramo značajke “Babel” i “Router”…

Pa, 3.x …

Y tipka za “history mode” u ruteru…

Zatim, “In dedicated config files”…

Imamo i opciju da spremimo naše postavke projekta kao preset, što znači Y tipka…

Ulazimo u mapu “my-project” i instaliramo libse:

npm install vuex

I na kraju pokrećemo dev server:

npm run serve

index.html

U index.html dodajemo css framework s kojim ćemo raditi a možemo ubaciti i web font:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>myproject</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link href="https://cdn.lineicons.com/4.0/lineicons.css" rel="stylesheet" />
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

App.vue

App.vue je osnovna komponenta u Vue.js projektima, koja predstavlja glavnu komponentu vaše web aplikacije. U ovoj datoteci definirate strukturu i izgled glavnog okvira vaše aplikacije.

Sadržaj:

<template>
  <nav>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </nav>
  <router-view/>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

Ovdje su ključni dijelovi App.vue datoteke:

  • <template>: Ovo je HTML dio vaše komponente gdje definirate strukturu vaše aplikacije. Unutar <template> možete imati HTML oznake za zaglavlje, glavni sadržaj i podnožje vaše web stranice. Također, možete koristiti Vue direktive za dinamičko prikazivanje podataka.
  • <script>: Ovdje možete napisati JavaScript kod za vašu komponentu. U primjeru App.vue, obično ne sadrži puno poslovne logike jer je namijenjen za upravljanje izgledom i komunikacijom između različitih dijelova aplikacije.
  • name: Ovo je naziv komponente, u ovom slučaju “App”.
  • <router-link>: Ovo je posebna oznaka koja se koristi za prikazivanje komponenata temeljem trenutne URL rute. Koristi se kada koristite Vue Router za navigaciju između različitih stranica ili ruta u vašoj aplikaciji.
  • <style>: Ovdje možete definirati CSS stilove za izgled vaše aplikacije. Stilovi koji se definiraju unutar ove sekcije primijenit će se samo na ovu komponentu.

Sadržaj App.vue datoteke je osnova vaše Vue.js aplikacije, a unutar nje možete dodavati i upravljati drugim komponentama kako biste izgradili kompletnu web aplikaciju.

Component

Vue komponenta je datoteka za višekratnu upotrebu koji sadrži HTML, CSS i JavaScript. Komponente se mogu koristiti za stvaranje složenih korisničkih sučelja sastavljanjem manjih dijelova kojima se lakše upravlja.

Naravno. Vue komponenta je komad koda za višekratnu upotrebu koji sadrži HTML, CSS i JavaScript. Komponente se mogu koristiti za stvaranje složenih korisničkih sučelja sastavljanjem manjih jedinica kojima se lakše upravlja.

Osnovni sadržaj Vue komponente sastoji se od tri dijela:

Oznaka <template>, koja definira HTML oznake za komponentu.
Oznaka <script>, koja definira JavaScript kôd za komponentu.
Oznaka <style>, koja definira CSS stilove za komponentu.


Evo primjera osnovne Vue komponente: /components/MyTest.vue:

<template>
  <div>
    <h1>Test Komponenta</h1>
  </div>
</template>

<script>
export default {
  name: 'MyTest',
}
</script>

<style>
.my-test {
  background-color: red;
}
</style>

Komponentu možemo uvesti i isprobati u App.vue:

<template>
  <nav>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </nav>
  <router-view/>  
  <test-component></test-component>
</template>


<script>

import MyTest from './components/MyTest.vue';

export default {
  name: 'App',
   components: {
    'test-component': MyTest, 
  }
}
</script>



<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

OK, usput možemo isprobati i Bootstrap 5. Kod možemo uzeti sa stranice:

https://getbootstrap.com/docs/5.0/components/buttons/

Ikonice imamo na:

https://lineicons.com/icons/

A u MyTest.vue komponentu unosimo:

<template>
  <div>
    <h1>Test Komponenta</h1>
    <button type="button" class="btn btn-primary btn-lg"><i class="lni lni-vuejs"></i> Large button</button>
  </div>
</template>

<script>
export default {
  name: 'MyTest',
}
</script>

<style>
.my-test {
  background-color: red;
}
</style>

Malo nam font na dugmetu bježi gore. To je zato što imamo css u App.vue.

Router

S ruterom možemo povezati url putanju sa komponentom. Što znači da, na primjer, možemo povezati putanju “/admin/login” sa komponentom “/components/admin/AdminLogin.vue”. Ruter podešavamo u datoteci “/src/router/index.js”.

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

Bitno je istaknuti da komponentu moramo uvesti:

import HomeView from '../views/HomeView.vue'

i navesti ju pod component:

  {
    path: '/',
    name: 'home',
    component: HomeView
  },

Što znači, da ako želimo staviti na test putanju “/test” , “MyTest” komponentu, moramo uvesti:

import HomeView from '../components/MyTest.vue'

A zatim:

  {
    path: '/test',
    name: 'test',
    component: MyTest
  },

State & storage

Vuex je biblioteka za upravljanje stanjem (state) u Vue.js aplikacijama. Ako ste razvijali složene Vue.js aplikacije, vjerojatno ste se susreli s potrebom za zajedničkim stanjem između različitih komponenata. Vuex rješava ovaj izazov pružajući centralizirano mjesto za pohranu i upravljanje podacima na razini cijele aplikacije.

U prijevodu ovo znači da uvijek imamo potrebe za globalnim varijablama a state (stanje) je event varijabla koja se idealno automatski primjenjuje svugdje u aplikaciji. Trebamo state, na primjer, da saznamo koja je aktivna stranica u izborniku.

Prije nego što nastavimo, pročistiti ćemo App.vue datoteku:

<template>
  <router-view/>  
</template>

State aplikacije postavljamo u “store.js” datoteci koja se eto zove “store” zato što: “The name ‘store’ is used because Vuex is designed to act as a centralized storage or container for managing the state of your Vue.js application.” Helikopter-zrakomalt…

store.js:

import { createStore } from 'vuex';

export default createStore({
  state: {
    count: 0,
    username: localStorage.getItem('store-username'),
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    setUsername(state, name) {
      state.username = name;
      localStorage.setItem('store-username', name);
    },
  }
});

Moramo uvesti vuex-ov store.js odnosno modificirati main.js:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

createApp(App).use(router).use(store).mount('#app')

Nadalje, izraditi ćemo dvije nove komponente s kojima ćemo testirati state.

./components/MyStateOne.vue

<template>
  <div class="container">
    <h1>MyStateOne</h1>
    
	<div class="btn-group">
	  <a href="/state/one" class="btn btn-outline-secondary active">State One</a>
	  <a href="/state/two" class="btn btn-outline-secondary">State Two</a>
	</div>
    
    <br><br>
    
    <div class="alert alert-primary" role="alert">
	  {{ count }}
	</div>
    <div class="alert alert-primary" role="alert">
	  {{ username }}
	</div>   
    
    <div class="btn-group">
	  <button @click="increment" class="btn btn-primary active">Increment Count</button>
	  <button @click="changeUsername" class="btn btn-primary">Change Username</button>
	</div>

  </div>
</template>

<script>
import { mapState, mapMutations  } from 'vuex';
export default {
  name: 'MyStateOne',
  
  computed: {
    ...mapState(['count']),
    ...mapState(['username']),
  },
  
  methods: {
    ...mapMutations(['increment']), 
    ...mapMutations(['setUsername']), 
    changeUsername() {
      this.$store.commit('setUsername', 'MyStateOne User One');
    },
  },
  
}
</script>

./components/MyStateTwo.vue

<template>
  <div class="container">
    <h1>MyStateTwo</h1>
    
    <div class="btn-group">
	  <a href="/state/one" class="btn btn-outline-secondary">State One</a>
	  <a href="/state/two" class="btn btn-outline-secondary active">State Two</a>
	</div>
    
    <br><br>
    
    <div class="alert alert-primary" role="alert">
	  {{ count }}
	</div>
    <div class="alert alert-primary" role="alert">
	  {{ username }}
	</div>   
    
    <div class="btn-group">
	  <button @click="increment" class="btn btn-primary active" aria-current="page">Increment Count</button>
	  <button @click="changeUsername" class="btn btn-primary">Change Username</button>
	</div>

  </div>
</template>

<script>
import { mapState, mapMutations  } from 'vuex';
export default {
  name: 'MyStateTwo',
  
  computed: {
    ...mapState(['count']),
    ...mapState(['username']),
  },
  
  methods: {
    ...mapMutations(['increment']), 
    ...mapMutations(['setUsername']), 
    changeUsername() {
      this.$store.commit('setUsername', 'MyStateOne User Two');
    },
  },
  
}
</script>

I na kraju ovoga bloka, unosimo promjene i u ruter odnosno “./router/index.js”:

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import MyStateOne from '../components/MyStateOne.vue'
import MyStateTwo from '../components/MyStateTwo.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/state/one',
    name: 'state-one',
    component: MyStateOne
  },
  {
    path: '/state/two',
    name: 'state-two',
    component: MyStateTwo
  },
 
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

SEO

Za SEO možemo koristiti @vueuse/head paketić.

npm i @vueuse/head

U main.js unosimo:

import { createHead } from '@vueuse/head'

A zatim u createApp niz:

const head = createHead();
createApp(App).use(head).use(router).use(store).mount('#app');

U komponenti:

import { useHead } from '@vueuse/head'

useHead({
	title: "New title",
	meta: [
	{
	  name:"description",
	  content:"This is description..."
	}
	],
});

I to je to… Arhiva s projektom je ovdje:

SKINI ARHIVU

Nakon što raspakirate arhivu, cd u mapu i pokrenite naredbe:

npm install
npm run serve