Vue - Vue routes doesn´t exist - laravel

I have a project in Laravel + Vue. In Laravel i have some routes for create endpoints and start page.
Laravel Routes
Route::get('/', 'Auth\LoginController#showLoginForm');
Route::post('/login', 'Auth\LoginController#login');
Auth::routes();
Route::resource('gateways', 'GatewayController');
Route::resource('contadores', 'ContadorController');
'/' route go to Blade file with Login Component.
Login Component has this code.
<template>
<v-content slot="content">
<v-container class="fill-height" fluid>
<v-row align="center" justify="center">
<v-col cols="12" md="8">
<v-card class="elevation-12">
<v-toolbar dark flat>
<v-toolbar-title>LoRaWAN</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field
label="Usuario"
name="username"
prepend-icon="mdi-account"
type="text"
v-model="username"
/>
<v-text-field
label="Contraseña"
name="password"
prepend-icon="mdi-key"
:append-icon="value ? 'mdi-eye' : 'mdi-eye-off'"
#click:append="() => (value = !value)"
:type="value ? 'password' : 'text'"
v-model="password"
/>
</v-form>
</v-card-text>
<v-card-actions>
<v-btn block dark #click="submit()">Entrar</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</v-content>
</template>
<script>
export default {
data() {
return {
value: String,
username: "",
password: ""
};
},
methods: {
submit() {
axios
.post("http://127.0.0.1:8000/login", {
username: this.username,
password: this.password
})
.then(response => {
if (response.data.token != null) {
localStorage.setItem("token", response.data.token);
console.log("ok");
this.$router.push({
name: "lora",
params: { user: this.username }
});
}
})
.catch(function(errors) {
let error = errors.response.data.errors;
let mensaje = "Error no identificado";
if (error.hasOwnProperty("username")) {
mensaje = error.username[0];
} else {
mensaje = error.password[0];
}
Swal.fire({
title: "Error",
text: mensaje,
icon: "error",
confirmButtonText: "Ok"
});
});
}
}
};
</script>
As we can see when login endpoint return token we want to push to other 'lora' route.
Vue routes file
import ContadorComponent from "./components/contador/ContadorComponent.vue";
import GatewayComponent from "./components/gateway/GatewayComponent.vue";
import HomeComponent from "./components/home/HomeComponent.vue";
import MainComponent from "./components/main/MainComponent.vue";
const routes = [{
path: "/lora",
name: "lora",
component: MainComponent,
props: true,
children: [{
path: "",
name: "home",
component: HomeComponent
},
{
path: "contadores",
name: "contadores",
component: ContadorComponent
},
{
path: "gateways",
name: "gateways",
component: GatewayComponent
}
]
}];
const router = new VueRouter({
mode: 'history',
routes: routes
});
new Vue({
vuetify: new Vuetify(),
router
}).$mount("#app");
And lora route (Main Component)
<template>
<v-app id="app">
<layoutDrawer></layoutDrawer>
<layoutHeader></layoutHeader>
<v-content>
<router-view></router-view>
</v-content>
<layoutFooter></layoutFooter>
</v-app>
</template>
<script>
import layoutHeader from "./partials/HeaderComponent.vue";
import layoutFooter from "./partials/FooterComponent.vue";
import layoutDrawer from "./partials/SidebarComponent.vue";
export default {
props: {
username: { type: String, default: "Invitado" }
},
components: {
layoutHeader,
layoutDrawer,
layoutFooter
}
};
</script>
The problem: If i go to http://127.0.0.1:8000/lora returns that this route doesn´t exist. In the vue routes file i declare it, so i don´t know why returns this. Maybe Laravel generate a conflict or something with routes. In laravel routes file i test this code and works
Route::get('/test', function () {
return view('home');
})->name('home');
The view home is blade file with Main Component. Maybe something happens with the vue routes that project doesn't recognize and only works Laravel routes..
The question: Are the vue routes properly declares? Anybody see some error?

Your client and server are running on the same port: http://127.0.0.1:8000.
The url for your lora route should be something like http://127.0.0.1:8001/lora

I found a partially solution. In Laravel routes i need to put this
Route::get('{any?}', function () {
return view('layout');
})->where('any', '.*');
Every time the user push to another page load Layout blade.
#extends('layouts.app')
#section('content')
<layout-component></layout-component>
#endsection
Layout Component
<template>
<v-app id="app">
<router-view></router-view>
</v-app>
</template>

Related

VUE js How hide routes by role in vue-router? Spa Laravel Vue

I am writing a SPA application (laravel + vue). There was a question how to hide routes in vue-router before authorization of a user with a certain role.
Now there is such a router.js fight with routes.
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../components/Calendar.vue'
import PermissionList from '../components/PermissionList.vue'
import BoardsList from '../components/BoardsList.vue'
import UsersList from '../components/UsersList.vue'
import Login from '../components/Login.vue'
const routes = [{
path: '/',
name: 'Home',
component: Home
},
{
path: '/permission-list',
name: 'PermissionList',
component: PermissionList
},
{
path: '/boards-list',
name: 'BoardsList',
component: BoardsList
},
{
path: '/users-list',
name: 'UsersList',
component: UsersList
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/dsad',
name: 'asd',
component: Login
},
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
linkActiveClass: "active",
})
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('token');
if (!token) {
if (to.name == 'Login') {
next();
} else {
next({
name: 'Login'
});
}
} else {
if (to.name == 'Login') {
next({
name: 'Home'
});
} else {
next();
}
}
})
export default router
User data including his role and jwt token come after authorization and are stored in localstorage.
<template>
<main class="form-signin text-center">
<div>
<h1 class="h3 mb-3 fw-normal">Form</h1>
<div class="form-floating">
<input
type="text"
class="form-control"
placeholder="Login"
v-model="login"
/>
<label for="floatingInput">Login</label>
</div>
<div class="form-floating my-2">
<input
type="password"
class="form-control"
placeholder="Pass"
v-model="password"
/>
<label for="floatingPassword">Pass</label>
</div>
<a class="w-100 btn btn-lg btn-primary" #click="logIn()">
Login
</a>
</div>
</main>
</template>
<script>
export default {
name:'Login',
data() {
return {
login:"",
password:"",
};
},
methods: {
logIn() {
this.HTTP.get('/sanctum/csrf-cookie').then(response => {
this.HTTP.post("/login",{
email:this.login,
password:this.password,
})
.then((response) => {
localStorage.setItem('token',response.config.headers['X-XSRF-TOKEN']);
localStorage.setItem('user',JSON.stringify(response.data.user));
this.$emit('loginUpdate');
this.$router.push('/');
})
.catch((error) => {
console.log(error);
});
});
},
},
};
</script>
<style>
.form-signin {
width: 100%;
max-width: 330px;
padding: 15px;
margin: auto;
}
.form-signin .checkbox {
font-weight: 400;
}
</style>
if you go to the vue developer panel, all routes will be visible even before the user is authorized, how can I hide them so that unauthorized users do not see the site structure.
did you solve this problem?
Just use separated js file using your mixin laravel config. One login.js, another app.js and then use each of them in separated view-laravel

what am I doing wrong by passing a prop from the parent to the child in vue if it only works in the template side?

So i am trying to do a basic WebSocket notification system. I am passing the user as a prop from App.vue to the navbar component. it Can be shown in the template but when I try to call it in the script section. it says undefined.You can take a look at this picture, it shows the id shown in the navbar and when I try to console.log it, it says undefined.
Here is my App.vue "The parent"
<template lang="">
<div>
<v-app>
<template v-if="isLoggedIn">
<AdminMenu></AdminMenu>
</template>
<template v-else-if="!isUserLoggedIn">
<Nav></Nav>
</template>
<template v-if="isUserLoggedIn">
<Navbar :user='user.id'></Navbar>
</template>
<v-main app>
<router-view></router-view>
</v-main>
</v-app>
</div>
</template>
<script>
import 'vuetify/dist/vuetify.min.css' // Ensure you are using css-loader
import axios from 'axios';
import AdminMenu from './layouts/AdminMenu.vue'
import Navbar from './layouts/user/Navbar.vue'
import Nav from './layouts/user/Nav.vue'
export default {
name:'app',
components:{ 'AdminMenu': AdminMenu, 'Navbar':Navbar, 'Nav':Nav},
data(){
return{
user:[],
isLoggedIn: false,
isUserLoggedIn: false,
}
},
created() {
if (window.Laravel.isLoggedin) {
this.isLoggedIn = true
}
if (window.Laravel.isUserLoggedin) {
this.isUserLoggedIn = true
}
},
mounted(){
this.axios.get('/api/user').then(response=>{
this.user = response.data
}).catch(error=>{
console.log(error)
})
},
}
</script>
Here is the child
<template lang="">
<div>
<v-toolbar app dark>
<span class="hidden-sm-and-up">
<v-toolbar-side-icon #click="sidebar = !sidebar">
</v-toolbar-side-icon>
</span>
<v-toolbar-title>
<router-link to="/" tag="span" style="cursor: pointer">
{{ appTitle }}
</router-link>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-xs-only">
<v-btn
text
v-for="item in menuItems"
:key="item.title"
:to="item.path">
{{ item.title }}
</v-btn>
<v-btn flat icon color="primary" disabled>
<v-icon></v-icon>{{user}}
</v-btn>
<v-btn #click="logout">Logout</v-btn>
</v-toolbar-items>
</v-toolbar>
</div>
</template>
<script>
export default {
name: "nav",
props:['user'],
data(){
return {
appTitle: 'My template',
sidebar: false,
menuItems: [
{ title: 'Home', path: '/home', icon: 'home' },
{ title: 'Profile', path: '/profile', icon: 'face' },
]
}
},
created(){
console.log(this.user)
},
methods: {
logout(e) {
console.log('ss')
e.preventDefault()
this.axios.get('/sanctum/csrf-cookie').then(response => {
this.axios.post('/api/logout')
.then(response => {
if (response.data.success) {
window.location.href = "/"
} else {
console.log(response)
}
})
.catch(function (error) {
console.error(error);
});
})
},
},
};
</script>
<style lang="">
</style>
First of all define your user in data() with default values so you should not recieve undefined error Moreover there is no async/await when you are calling api in the mounted state
App.vue
<template>
<div>
<v-app>
<template v-if="isLoggedIn">
<AdminMenu></AdminMenu>
</template>
<template v-else-if="!isUserLoggedIn">
<Nav></Nav>
</template>
<template v-if="isUserLoggedIn">
<Navbar :user='user.id'></Navbar>
</template>
<v-main app>
<router-view></router-view>
</v-main>
</v-app>
</div>
</template>
<script>
import 'vuetify/dist/vuetify.min.css' // Ensure you are using css-loader
import axios from 'axios';
import AdminMenu from './layouts/AdminMenu.vue'
import Navbar from './layouts/user/Navbar.vue'
import Nav from './layouts/user/Nav.vue'
export default {
name:'app',
components:{ 'AdminMenu': AdminMenu, 'Navbar':Navbar, 'Nav':Nav},
data(){
return{
user:[],
isLoggedIn: false,
isUserLoggedIn: false,
}
},
created() {
if (window.Laravel.isLoggedin) {
this.isLoggedIn = true
}
if (window.Laravel.isUserLoggedin) {
this.isUserLoggedIn = true
}
},
async mounted(){
await this.axios.get('/api/user').then(response=>{
this.user = response.data
}).catch(error=>{
console.log(error)
})
},
}
</script>

No http lib found to perform ajax request in VJSF

I use VJSF to fill selects using the results from HTTP requests.
Then I faced a bug that is stressful.
Following is my code.
<template>
<v-app id="app">
<v-container>
<p>valid={{valid}}</p>
<v-form ref="form" v-model="valid">
<v-jsf v-model="model" :schema="schema" :options="options" #input="logEvent('input', $event)" #change="logEvent('change', $event)" />
</v-form>
<v-layout row class="mt-2">
<v-spacer></v-spacer>
<v-btn color="primary" #click="$refs.form.validate()">Validate</v-btn>
</v-layout>
</v-container>
</v-app>
</template>
<script>
import VJsf from '#koumoul/vjsf/lib/VJsf.js'
import '#koumoul/vjsf/lib/VJsf.css'
import '#koumoul/vjsf/lib/deps/third-party.js'
const model = {
selectAjaxString: 'https://koumoul.com/s/data-fair/api/v1/datasets/gendarmeries-france-metropolitaine'
}
const options = {
context: {
owner: {
type: 'organization',
id: '5a5dc47163ebd4a6f438589b'
}
},
idPrefix: 'example-select-http-'
}
const schema = {
type: 'object',
properties: {
selectAjaxString: {
type: 'string',
title: 'I\'m a string selected from results of an HTTP request',
'x-fromUrl': 'https://koumoul.com/s/data-fair/api/v1/datasets?status=finalized&select=title&owner={context.owner.type}:{context.owner.id}',
'x-itemsProp': 'results',
'x-itemTitle': 'title',
'x-itemKey': 'href'
}
}
}
export default {
name: 'App',
components: { VJsf },
data: () => ({
model,
options,
schema,
valid: false
}),
methods: {
logEvent(key, $event) {
console.log("vjsf event", key, $event);
}
}
};
</script>
What is the reason?
Why I can not perform ajax request?
I followed sample in https://koumoul-dev.github.io/vuetify-jsonschema-form/latest/examples#select-http
It looks like VSJF requires users to specify an HTTP request library via the httpLib configuration option:
Install axios:
npm i -S axios
Update your VSJF configuration options to set axios as the httpLib:
import axios from 'axios'
const options = {
//...
httpLib: axios
}

<router-view> in laravel 5.6 and vue.js don't work

I do not know what I'm doing wrong, but my router-view does not work.
I have an app based on Laravel 5.6 and I want to make views through vue.js.
Components "Navbar" and "Foot" are load correctly but I don't see "Home" component which should be load by in App.vue
Routing also does not work. When I type in the browser /about I get an error "Sorry, the page you are looking for could not be found."
Below my files:
App.vue
<template>
<div class="app">
<Navbar/>
<router-view></router-view>
<Foot/>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return{
}
}
}
</script>
Home.vue
<template>
<div class="home">
<h1>Home</h1>
</div>
</template>
<script>
export default {
name: 'Home',
data () {
return {
}
}
}
</script>
About.vue
<template>
<div class="about">
<h1>O nas</h1>
</div>
</template>
<script>
export default {
name: 'About',
data (){
return{
}
}
}
</script>
app.js
require('./bootstrap');
import Vue from 'vue';
import VueRouter from 'vue-router';
import Vuex from 'vuex';
window.Vue = require('vue');
Vue.use(VueRouter);
Vue.use(Vuex);
let AppLayout = require('./components/App.vue');
// home tempalte
const Home = Vue.component('Home', require('./components/Home.vue'));
// About tempalte
const About = Vue.component('About', require('./components/About.vue'));
// register components
const Navbar = Vue.component('Navbar', require('./components/Navbar.vue'));
const Foot = Vue.component('Foot', require('./components/Foot.vue'));
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
name: 'About',
path: '/about',
component: About
}
];
const router = new VueRouter({ mode: 'history', routes: routes});
new Vue(
Vue.util.extend(
{ router },
AppLayout
)
).$mount('#app');
You need to teach laravel's router how to play along with vue's.
Check out this link: https://medium.com/#piethein/how-to-combine-vuejs-router-with-laravel-1226acd73ab0
You need to read around where it says:
Route::get('/vue/{vue_capture?}', function () {
return view('vue.index');
})->where('vue_capture', '[\/\w\.-]*');

How to Authenticate User using Laravel Api routes and Vue 2 Js and Vue Router

My goal is that laravel has an implemented Authorization Provider for us
https://laravel.com/docs/5.3/authentication
so I want to authenticate my users by using that by an API and set it back to my Vue Router
and authorize the users
How can i implement it?
Im always getting an error on authentication
im using axios as my HTTP provider
Here is the app.js
require('./bootstrap');
import VueRouter from 'vue-router';
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
Vue.use(VueRouter);
axios.defaults.baseURL = '/api';
axios.defaults.headers.common['X-CSRF-TOKEN'] = window.Laravel.csrfToken;
import LoginForm from './components/LoginForm.vue';
import RegisterForm from './components/RegisterForm.vue';
Vue.component('login-form',LoginForm)
Vue.component('register-form',RegisterForm)
// Directives
const routes = [
{ path: '/', component: require('./pages/Index.vue') },
{ path: '/admin/users', component: require('./pages/admin/Users.vue') },
{ path: '/user/:id', component: require('./pages/user/Dashboard.vue'),
children: [
// UserHome will be rendered inside User's <router-view>
// when /user/:id is matched
{ path: '', component: require('./pages/user/Index.vue')},
// UserPosts will be rendered inside User's <router-view>
// when /user/:id/posts is matched
{ path: 'settings', component: { template: '<div>Settings</div>' } },
]
},
{ path: '/manager/:id', component: require('./pages/user/Dashboard.vue'),
children: [
// UserHome will be rendered inside User's <router-view>
// when /user/:id is matched
{ path: '', component: require('./pages/user/Index.vue')},
// UserPosts will be rendered inside User's <router-view>
// when /user/:id/posts is matched
{ path: 'settings', component: require('./pages/user/Settings.vue') },
]
},
{ path: '/store/:id', component: require('./pages/user/Dashboard.vue'),
children: [
// UserHome will be rendered inside User's <router-view>
// when /user/:id is matched
{ path: '', component: require('./pages/user/Index.vue')},
// UserPosts will be rendered inside User's <router-view>
// when /user/:id/posts is matched
{ path: 'settings', component: { template: '<div>Settings</div>' } },
]
},
{ path: '/*', component: require('./pages/404.vue') },
];
const router = new VueRouter({
routes,
});
const app = new Vue({
el: '#app',
router,
template: `<div id="#app">
<router-view></router-view>
</div>`,
})
Here is the a Login form component
<template>
<form class="form" #submit.prevent='submitForm'>
<div class="form-group">
<input type="email" class="form-control" name="email" v-model="login.email" placeholder="Email">
</div>
<div class="form-group">
<input type="password" class="form-control" name="password" v-model="login.password" placeholder="Password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-info btn-block"> Login </button>
</div>
</form>
</template>
<script>
export default {
data() {
return {
errors: [],
login: {
email: '',
password: '',
_token: window.Laravel.csrfToken
}
}
},
methods: {
submitForm() {
this.axios.post('/login',this.login)
.then(response => {
})
.catch(response => {
})
}
}
}
</script>
this is my Laravel API
in api.php
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group(['middleware' => 'auth'], function () {
Route::get('/auth',function() {
return Auth::user();
});
Route::resource('/users','UserController');
Route::resource('/stores','StoreController');
Route::resource('/items','ItemController');
Route::resource('/transactions','StoreController');
Route::resource('/managers','ManagerController');
Route::resource('/employees','EmployeeController');
Route::resource('/customers','CustomerController');
Route::resource('/tags','TagController');
});
Route::group(['middleware' => 'web'], function() {
Auth::routes();
});
So my BIG PROBLEM here is the authentication using vue i'm used to authentication in blade templates and laravel routes but not on vue

Resources