Laravel + Vue spa two step router not working - javascript

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!

Related

Vue-Router not rerouting in Single Page Application (Vue/Laravel)

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');
}
}

Vue router is not routing

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>

Making a SPA using vue but having some trouble

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.

Hide vue router from a page

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>

How to reuse react components in different html pages

im having problems with re-using react components in two different html pages
heres the structure of my app
react app
|-- webpack.config
|-- package
`-- src
|-- index.js
|-- index.html
|-- home.html
`-- components
|-- Main.js
|-- Sector.js
|-- Homepage.js
okay in webpack.config i have
this
module.exports = {
entry: './index.js',
entry: [
'webpack-dev-server/client?http://127.0.0.1:' + defaultSettings.port,
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.join(__dirname, '/../dist/assets'),
filename: 'app.js',
},
module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }
]
}
}
in index.js
import 'core-js/fn/object/assign';
import React from 'react';
import ReactDOM from 'react-dom';
import Appd from './components/Main';
import Sector from './components/sector';
import Homepagesector from './components/Homepagesector';
ReactDOM.render(<Appd />, document.getElementById('app'));
ReactDOM.render(<Sector />, document.getElementById('sector'));
ReactDOM.render(<Homepagesector />, document.getElementById('homepage'));
in index.html
<!doctype html>
<html >
<head>
<meta charset="utf-8">
<title>zilla</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="">
</head>
<!-- REQUIRED 3/3 - the image crop directive -->
<body >
<header>
<div id="app"></div>
</header>
<script src="appcontroller.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__</script>
<script type="text/javascript" src="/assets/app.js"></script>
<script type="text/javascript" src="resample.js"></script>
<script type="text/javascript" src="avatar.js"></script>
</body>
</html>
in home.html
<html>
<head>
</head>
<body >
<header>
<div id="homepage"></div>
</header>
<script src="appcontroller.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__</script>
<script type="text/javascript" src="/assets/app.js"></script>
<script type="text/javascript" src="resample.js"></script>
<script type="text/javascript" src="avatar.js"></script>
<script type="text/javascript" src="avatar.js"></script>
</body>
</html>
In components folder
Main.js
require('styles/App.css');
import React from 'react';
let yeomanImage = require('../images/zilla.png');
class AppComponent extends React.Component {
render() {
return (
<div>
<img src={yeomanImage} alt="Yeoman Generator" />
<h1 className="title"></h1>
<li>
<a href="index2.html" className="a7" >Signin</a>
</li>
<li>
<a href="index.html" className="a7" >Register</a>
</li>
</div>
In components folder
Sector.js
require('styles/sector.css');
import React from 'react';
let yeomanImage = require('../images/dealzilla.png');
let yeomanImaged = require('../images/256.jpg');
class AppComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
data: 'Initial data...'
}
this.updateState = this.updateState.bind(this);
};
updateState(e) {
this.setState({data: e.target.value});
}
render() {
return (
<div className="page-wrap">
<h1>not registered?register for free</h1>
<div className="profile">
<div className="profile-avatar-wrap">
<img src={yeomanImaged} alt="Yeoman Generator" id="profile-avatar" alt="Image for Profile"/>
</div>
<div className="location">upload avatar</div>
</div>
<h3>You could do this with a file input too...</h3>
<div>
<input type = "text" value = {this.state.data}
onChange = {this.updateState} />
<h4>{this.state.data}</h4>
</div>
</div>
In components folder
homepage.js
import React from 'react';
let yeomanImage = require('../images/dealzilla.png');
class AppedComponent extends React.Component {
render() {
return (
<div>
<img src={yeomanImage} alt="Yeoman Generator" />
<h1 className="title">dealzilla</h1>
<li>
<a href="index2.html" className="a7" >Search</a>
<a href="index2.html" className="a7" >Search</a>
</li>
<li>
<a href="index.html" className="a7" >Register</a>
</li>
</div>
);
}
}
AppedComponent.defaultProps = {
};
export default AppedComponent;
The problem is that I am not able to use homepage.js component
in my home.html page
it doesnt appear at all
however my Main.js component is able to appear
Im still a beginner in react, I've looked around for answers and didnt find any on this regard
any help would be appreciated
thank you in advance
best regards
heres what i ended up using maybe it will help someone out there who also got stuck
https://ui-router.github.io/react/
its a great tool to use with react coming from angular

Categories

Resources