Vue aplikace pro přístup k API č.7 – Vytvoříme si základní layout aplikace
- Vue aplikace pro přístup k API č.1 – Instalace Vue
- Vue aplikace pro přístup k API č.2 – Připojení k našemu API
- Vue aplikace pro přístup k API č.3 – Přidáme si do Vue stránky
- Vue aplikace pro přístup k API č.4 – Přihlášení ve Vue
- Vue aplikace pro přístup k API č.5 – Zabezpečení stránek pouze pro přihlášené
- Vue aplikace pro přístup k API č.6 – Přidáme si Vuetify
- Vue aplikace pro přístup k API č.7 – Vytvoříme si základní layout aplikace
- Vue aplikace pro přístup k API č.8 – Vypíšeme si produkty v naší vue aplikaci
Tak v projektu máme nasitalováno vuetify a chtěla bych si vytvořit resposivní navigaci pro všechny stránky, kromě přihlašovací. Tak pojďme na to
Upravíme si App.vue taky aby mán vždy pro autentifikované uživatele nahoře zobrazilo se společné menu aplikace buď jako horizonatální navigave na desktopu nebo jako hamburger menu na mobilních rozlišeních
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
<!-- App.vue --> <template> <v-app> <!-- Layout pro autentizované stránky --> <template v-if="!isLoginPage"> <!-- Mobilní drawer menu --> <v-navigation-drawer v-model="drawer" temporary v-if="isAuthenticated" class="d-sm-none" > <v-list> <v-list-item prepend-icon="mdi-home" title="Home" :to="{ name: 'Home' }" /> <v-list-item prepend-icon="mdi-account" title="Uživatelé" :to="{ name: 'Users' }" /> <v-list-item prepend-icon="mdi-package-variant" title="Produkty" :to="{ name: 'Products' }" /> <v-list-item prepend-icon="mdi-logout" title="Odhlásit" @click="handleLogout" /> </v-list> </v-navigation-drawer> <v-app-bar v-if="isAuthenticated"> <!-- Hamburger menu pouze pro mobilní zobrazení --> <v-app-bar-nav-icon @click="drawer = !drawer" class="d-sm-none" ></v-app-bar-nav-icon> <v-app-bar-title>Moje Aplikace</v-app-bar-title> <!-- Horizontální menu pro desktop --> <div class="d-none d-sm-flex ml-4"> <v-btn v-for="item in menuItems" :key="item.title" :to="item.to" variant="text" > <v-icon start>{{ item.icon }}</v-icon> {{ item.title }} </v-btn> </div> <v-spacer></v-spacer> <v-btn icon @click="handleLogout"> <v-icon>mdi-logout</v-icon> </v-btn> </v-app-bar> </template> <v-main> <router-view></router-view> </v-main> </v-app> </template> <script> import authService from '@/services/auth' export default { name: 'App', data() { return { drawer: false, menuItems: [ { title: 'Home', icon: 'mdi-home', to: { name: 'Home' } }, { title: 'Uživatelé', icon: 'mdi-account', to: { name: 'Users' } }, { title: 'Produkty', icon: 'mdi-package-variant', to: { name: 'Products' } } ] } }, computed: { isLoginPage() { return this.$route.name === 'Login' }, isAuthenticated() { return authService.isAuthenticated() } }, methods: { async handleLogout() { await authService.logout() this.$router.push({ name: 'Login' }) } } } </script> <style scoped> .v-btn { text-transform: none; } </style> |
a také si upravíme přihlašovací stránku, která nebude zobrazovat menu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
<!-- views/Login.vue --> <template> <v-app> <div class="login-container"> <v-card style="width: 90%; max-width: 450px;" elevation="8"> <v-card-title class="text-center pt-6 pb-2"> <h2>Přihlášení</h2> </v-card-title> <v-card-text> <v-form @submit.prevent="handleLogin"> <v-text-field v-model="email" label="Email" prepend-icon="mdi-email" type="email" :rules="emailRules" /> <v-text-field v-model="password" label="Heslo" prepend-icon="mdi-lock" :type="showPassword ? 'text' : 'password'" :append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'" @click:append="showPassword = !showPassword" :rules="passwordRules" /> <v-btn block color="primary" size="large" type="submit" :loading="loading" class="mt-4 mb-3" > Přihlásit </v-btn> <v-alert v-if="error" type="error" class="mt-4" density="compact" > {{ error.message || 'Přihlášení se nezdařilo' }} </v-alert> </v-form> </v-card-text> </v-card> </div> </v-app> </template> <script> import authService from '@/services/auth' export default { name: 'Login', data() { return { email: '', password: '', loading: false, error: null, showPassword: false, emailRules: [ v => !!v || 'Email je povinný', v => /.+@.+\..+/.test(v) || 'Email musí být platný' ], passwordRules: [ v => !!v || 'Heslo je povinné', v => (v || '').length >= 6 || 'Heslo musí mít alespoň 6 znaků' ] } }, methods: { async handleLogin() { this.loading = true this.error = null try { const success = await authService.login({ email: this.email, password: this.password }) if (success) { const redirect = this.$route.query.redirect || '/' this.$router.push(redirect) } } catch (error) { console.error('Chyba:', error) this.error = error } finally { this.loading = false } } } } </script> <style scoped> .login-container { min-height: 100vh; width: 100%; display: flex; align-items: center; justify-content: center; background-color: #f5f5f5; overflow: hidden; position: fixed; top: 0; left: 0; right: 0; bottom: 0; } </style> |
Takže vše řádně otestujeme, pokud nejsme přihlášeni zobrazí se nám login
a po přihlášení se na desktopu zobazí takto
a na mobilu