I am trying to get vue-router to work in a Vue.js/Laravel project. I have the following simple pages:
home page:
about page (scrolled down in single page):
Made from these files:
welcome.blade.php:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=WeakMap"></script>
<title>title</title>
</head>
<body id="body">
<div id="app">
<app></app>
</div>
</body>
<script src="{{ mix('js/app.js') }}"></script>
</html>
app.vue:
<template>
<div class="container">
<main>
<home></home>
<about></about>
</main>
</div>
</template>
<script>
import About from "./about"
import Home from "./home";
export default {
name: "app",
components: {
About,
Home,
}
}
</script>
<style lang="scss">
</style>
home.vue:
<template>
<section class="home" style="background-color: yellow; height: 100vh">
<h1>Home Page</h1>
</section>
</template>
<script>
export default {
name: "home"
}
</script>
<style scoped lang="scss">
</style>
about.vue:
<template>
<section class="about" style="background-color: green; height: 100vh">
<h2>About Page</h2>
</section>
</template>
<script>
export default {
name: "about"
}
</script>
<style scoped lang="scss">
</style>
web.php:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
app.js:
require('./bootstrap')
import Vue from "vue"
import App from "../vue/app"
import router from "./router";
const app = new Vue({
el: "#app",
components: { App },
router
})
router.js:
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../vue/home";
import About from "../vue/about";
Vue.use(VueRouter);
export default new VueRouter({
mode: "history",
routes: [
{ path: "/", component: Home},
{ path: "/about", component: About}
]
});
Now, if I add <router-view></router-view> to app.vue like this:
<template>
<div class="container">
<main>
<home></home>
<about></about>
</main>
</div>
<router-view></router-view>
</template>
The site doesn't load at all and the browser console shows no errors:
Path localhost:3000/about shows an 404 Error:
What am I doing wrong?
Did you try to define base in router:
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
export default router;
Then in app:
<template>
<div class="container">
<nav>
<router-link
to="/"
tag="a"
>Home</router-link>
<router-link
to="/about"
tag="a"
>About</router-link>
</nav>
</div>
<router-view></router-view>
</template>
In Laravel you need a catch-all route that redirects all routes to your Vue project:
Create a new controller called something like VueController, then direct all your routes in Laravel to it:
Route::get('/{any}', 'VueController#index')->where('any', '.*');
Then in your VueController return your welcome blade:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class VueController extends Controller
{
public function index()
{
return view('welcome');
}
}
Related
When directing to '/' the "mainapp im here" message is showing but the routing
to homepage is not happening , below is my code , this is my first time using Vue
and im trying to work with it, the problem it's not routing note that
it's accessing the router.js
----- web.php
// Client Routes
Route::get('/', 'Client\HomeController#index');
----- HomeController.php
<?php
namespace App\Http\Controllers\Client;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Package;
class HomeController extends Controller
{
public function index()
{
return view('client.home.index');
}
}
----- Index.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
</head>
<body>
<div id="app">
<mainapp> </mainapp>
</div>
</body>
<script src="./js/app.js"></script>
</html>
----- mainapp.vue
<template>
<div>
<h1>mainapp im heree</h1>
<router-view> </router-view>
</div>
</template>
----- Router.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import homePage from './components/pages/homePage.vue'
const routes =[
{
path:'/',
component: homePage
}
]
export default new Router ({
mode: 'history',
routes
})
-----app.js
require('./bootstrap');
window.Vue = require('vue');
import router from './router'
Vue.component('mainapp', require('./components/mainapp.vue').default);
const app = new Vue({
el: '#app',
router
})
-----Homepage.vue
<template>
<div>
<h1>hello</h1>
</div>
</template>
Laravel: 7.17, Vue: 2.5.17.
I made simple sidebar and tried to work that.
One step router ( /admin, /home, /... ) worked well but two steps router(/admin/blog/category, /admin/blog/post...) didn't work.
Here is what I did.
-routes/web.php
Route::get('/{any?}', function() {
return view('app');
})->where('any', '.*');
-resources/views/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<div id="app">
<div class="container mx-auto">
<main class="d-flex">
<aside class="w-25">
<section>
<ul>
<li><router-link to="/admin">Dashboard</router-link></li>
</ul>
</section>
<section>
<h6>Blog </h6>
<ul class="list-group">
<li><router-link to="/admin/blog/category">Category</router-link></li>
<li><router-link to="/admin/blog/post">Posts</router-link></li>
</ul>
</section>
</aside>
<div class="p-3">
<router-view></router-view>
</div>
</main>
</div>
</div>
<script src="/js/app.js"></script>
</body>
</html>
-resources/js/app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes';
Vue.use(VueRouter);
const app = new Vue({
el: '#app',
router: new VueRouter(routes)
});
-resources/js/routes.js
import Home from './components/Home';
import Admin from './components/admin/Admin';
import Category from './components/admin/blog/Category';
import Post from './components/admin/blog/Post';
import PathThrough from './components/PathThrough';
export default {
mode:'history',
routes:[
{
path:'/',
component: Home
},
{
path:'/admin',component: Admin,
children: [
{
path:'blog', component: PathThrough,
children: [
{ path: 'category', component: Category},
{ path: 'post', component: Post},
]
}
]
},
]
};
-resources/js/components/PathThrough.vue
<template>
<router-view></router-view>
</template>
<script>
export default {};
</script>
-other components
<template>
<h1>Home Page</h1>
</template>
<script>
export default {};
</script>
Here, /admin and / routes are working.
But other routes don't work.
Can anyone help me?
Thank you!
I'have multiple auth laravel dashboard. When i login the default page redirect me to the client dashboard blade. When i write something in client blade.It does not show anything.I am using vuejs routers. Everything is working perfect. I tried to call component in that blade but it's still showing blank .I want to redirect to dashboard component.
Controller:
I tried it with the return url('url here') but still not working for me.
public function index()
{
return view('client');
}
Client Blade:
#extends('layouts.master')
#section('content')
<template>
<div class="container-fluid">
<client_details></client_details>
</div>
</template>
<script>
import clientdetails_header from "./clientdetails_header.vue";
export default {
data() {
return {
}
},
components: {
'client_details': clientdetails_header
},
mounted() {
console.log('Component mounted.')
}
}
</script>
#endsection
Master Blade:
<ul>
<li>
<router-link to="/clientdashboard" title="dashboard">
<span class="nav-link-text"><iclass="fal fa-user"></i>DashBoard</span>
</router-link>
</li>
</ul>
<div class="page-wrapper" id="app">
<div class="page-content">
<router-view>
</router-view>
</div>
</div>
App.js
let routes = [
{path: '/clientdashboard', component: require('./components/clientdashboard.vue').default},
]
const app = new Vue({
el: '#app',
router,
});
const router = new VueRouter({
mode: "history",
routes
})
ClientHeader:
<template>
<div class="row">
<div class="col-xl-12">
<!-- Collapse -->
<div id="panel-6" class="panel">
<div class="panel-hdr">
<h2>
Client Details
</h2>
</div>
<div class="panel-container show">
<div class="panel-content">
<div class="row">
<div class="col-md-2">
<span><b>Company name:</b></span> <br>
<span><b>Company ABN:</b></span> <br>
<span><b>Company address:</b></span> <br>
<span><b>Company phone:</b></span> <br>
<span><b>Company email:</b></span> <br>
</div>
<div class="col-md-10">
<ul style="list-style: none;" class="list-group list-group-flush">
<li style="text-decoration: none" v-for="todo in clientData">{{todo}}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
user_id: this.$userId,
clientData: {}
}
},
methods: {
getClientDetails() {
axios.post(this.$path + 'api/getClientDetails', null,
{
params: {
'client_id': this.user_id,
}
})
.then(data => (
this.clientData = data.data));
}
},
mounted() {
this.getClientDetails();
console.log('Component mounted.')
}
}
</script>
I don't think it's a good idea trying to put Vue code directly inside blade.
I would suggest you create a Client.vue and put your code in it instead. Register it in your routes in app.js.
...
{path: '/client', component: require('./components/Client.vue')},
Then you can use the component in your Client blade.
<client></client>
I believe that would be a first step towards resolving this issue.
Load your app.js in <head> section of your blade.php
<script src="{{ asset('js/app.js') }}" async></script>\
Also create a div with id app there.
<body>
<div id="app"></div>
</body>
Create App.vue
<template>
<div>
<router-view />
</div>
</template>
<style scoped lang="scss">
</style>
Go to resources/js/app.js file, you will see laravel already put code to instantiate vue in there. Register your route etc.
But for me, I create a new folder resources/js/vue, put all vue related files (components, routes, filters, vuex, mixins, directives) there, create index.js and moved the code to initiate vue inside index.js.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import components from './components'
import directives from './directives'
import mixins from './mixins'
import filters from './filters'
Vue.use(router)
Vue.use(store)
Vue.use(components)
Vue.use(directives)
Vue.use(mixins)
Vue.use(filters)
new Vue({ router, store, render: h => h(App) }).$mount('#app')
export default {}
resources/js/app.js
require('./vue')
// I also initiate service-worker, firebase, and other non vue related
// javascripts in this file
I am using Larvel (latest version) and I am attempting to make a SPA using vuejs. I followed a SPA tutorial in the laracast episodes about vue js. However, i am having a little bit of trouble. I think im doing something wrong in the routes.js file because in the tutorial it says to make the component be require(./views/home) but the require function is not being
resolved.
The problem is that on the page the router-link tag is not being compiled to an anchor tag
Boostrap.js
import Vue from 'vue';
import axios from 'axios';
import VueRouter from 'vue-router';
window.Vue = Vue;
Vue.use(VueRouter);
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
Router.js
import VueRouter from 'vue-router';
let routes = [
{
path:'/',
component: require('./views/home')
}];
export default new VueRouter({
routes
});
App.js
import './bootstrap';
import router from './routes'
new Vue({
el: '#app',
router
});
home.vue
<template>
<section class="hero is-dark">
<div class="hero-body">
<div class="container">
<h1 class="title">
Primary title
</h1>
<h2 class="subtitle">
Primary subtitle
</h2>
</div>
</div>
</section>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
nav
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
#include('partials.head')
<title>My App</title>
</head>
<body class="">
<div class="wrapper">
<div class="content-wrapper">
<div id="app">
<router-link to='/'>Home</router-link>
<router-link to='/about'>About</router-link>
</div>
</div>
</div>
#include('partials.footer')
</body>
</html>
Mix
mix.js('resources/assets/js/app.js', 'public/js')
When looking at your bootstrap.js, it seems you are doing Vue.use(‘VueRouter’). When calling the use method, you need to pass it the VueRouter object you imported, and not a string literal.
Is it possible to hide the vue-router from my login page? If so, how would I do that? On every page I have I see the menu, but on the Login page I don't want to see it.
Here is my code:
Login
<template>
<div>
<h1>Login</h1>
<form action="">
<label>naam</label>
<input type="text">
</form>
</div>
</template>
<script>
</script>
<style scoped>
h1 {
background-color: chartreuse;
}
</style>
App.vue
<template>
<div id="app">
<div class="routing">
</div>
<router-link to="/">Login</router-link>
<router-link to="/home">Home</router-link>
<router-view v-if="$route = 'login'"></router-view>
</div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
Main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import Login from './Login.vue'
import Home from './Home.vue'
Vue.use(VueRouter);
const routes = [
{ path: '/', component: Login},
{ path: '/home', component: Home},
];
const router = new VueRouter({
routes,
mode: 'history'
});
new Vue({
el: '#app',
router,
render: h => h(App)
});
Home.vue
<template>
<div>
<h1>Home</h1>
<hr>
<router-view></router-view>
</div>
</template>
<script>
</script>
<style scoped>
h1 {
background-color: aquamarine;
}
</style>
I just had the same problem and found 2 approaches:
1. Using nested routes - http://router.vuejs.org/en/essentials/nested-routes.html
Basically you have to use your App.vue as kind of a placeholder, with all the elements that are shared between all the pages (in your case I believe that is none), and place <router-view></router-view> inside it. For you I believe that will be as simples as:
//App.vue
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
And you also will have to have another template that will hold your menu:
//Restricted.vue
<template>
<div id="restricted">
<div class="routing">
</div>
<router-link to="/">Login</router-link>
<router-link to="/home">Home</router-link>
<router-view></router-view>
</div>
</template>
And in your router should have something like:
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import Login from './Login.vue'
import Home from './Home.vue'
import Restricted from '/.Restricted.vue';
Vue.use(VueRouter);
const routes = [
{ path: '/', component: Login},
{
path: '/restricted',
component: Restricted,
children: [
{ path: 'home', component: Home},
],
},
];
const router = new VueRouter({
routes,
mode: 'history'
});
new Vue({
el: '#app',
router,
render: h => h(App)
});
This way your Login page will be rendered at / and other pages (with menu) at /restricted/{other_page}. Using this approach the menu will not be displayed nor rendered.
2. Using v-if on the components that you do not want to render.
In you App.vue use v-if="this.$route.path !== '/'" on the elements that you do not want to be rendered, in your case, the router-link's. You could encapsulate them and apply v-if="this.$route.path !== '/'" to the encapsulation element (div?)
//App.vue
<template>
<div id="app">
<div class="routing" v-if="this.$route.path !== '/'">
<router-link to="/">Login</router-link>
<router-link to="/home">Home</router-link>
</div>
<router-view></router-view>
</div>
</template>
Regards.
You can use v-if for this:
<router-link v-if="!isOnLoginPage()" to="/">Login</router-link>
where isOnLoginPage can be a simple method, which returns true or false depending on current route.
isOnLoginPage: function() {
return this.$route.path === '/'
}
if your login path is '/login'
in your App.vue
<template>
<div id="app">
<div class="routing">
</div>
<router-link to="/" v-if="$route.fullPath !== '/login'">Login</router-link>
<router-link to="/home" v-if="$route.fullPath !== '/login'">Home</router-link>
<router-view v-if="$route.fullPath === '/login'"></router-view>
</div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>