How to access shared data from a layout component in Vue/Inertiajs - laravel

I have used this instruction from inertiajs official website to share user auth data and it works fine for all pages except those who doesn't directly rendered by Inertia::render() method.
I need to access user authentication data from a layout component named <Master> but I can't!
here is my structure/heirarchy:
- Vue/
- Pages/
- Home/
- Index.vue
- Layouts/
- Master.vue
- Header.vue
- Footer.vue
- App.js
here is my <Master> component:
<template>
<Head>
<title>My Title</title>
</Head>
<Header :user="user"/>
<slot/>
<Footer/>
</template>
<script>
import Header from './Header';
import Footer from './Footer';
import {Head} from '#inertiajs/inertia-vue3';
export default {
data() {
return {
user: this.auth.user,
}
},
props:{
auth: Object,
},
components: {
Header,
Footer,
Head,
}
}
</script>

You can use the $page property or the usePage() hook.
<Header :user="$page.props.auth.user" />
const user = computed(() => usePage().props.value.auth.user)
If you scroll down the the link you have given you will know it.

Related

Vue & Laravel problem with loading the components

I have a problem with my simple application using Vue 3, Vue router 4 & Laravel 8, my problem is that the main component is not loading I need to Ctrl + R to be able to see the main component and for the other component using Vue router nothing is loading properly this is my full code after downloading all the packages and run npm install , npm run dev & npm run watch :
app.js
require("./bootstrap");
import { createApp } from "vue";
import Main from "./components/App.vue";
import router from "./router";
const app = createApp({});
app.component("main-app", Main);
app.use(router);
app.mount("#app");
router.js
import { createRouter, createWebHistory, routerKey } from "vue-router";
import Home from "./components/pages/Home.vue";
import About from "./components/pages/About.vue";
import NotFound from "./components/pages/NotFound.vue";
const routes = [
{
path: "/Home",
name: "Home",
component: Home,
},
{
path: "/About",
name: "About",
component: About,
},
{
path: "/:catchAll(.*)",
component: NotFound,
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
// export default createRouter({
// history: createWebHistory(),
// routes,
// });
welcome.blade.php I named 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="{{ mix('css/app.css') }}">
</head>
<body>
<div id="app">
<main-app />
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
App.vue
<template>
<h1>Hello from the main app</h1>
<div id="nav">
<router-link to="/Home">Home</router-link> |
<router-link to="/About">About</router-link>
</div>
<router-veiw />
</template>
<script>
export default {};
</script>
About.vue, Home.vue & NotFound.vue
They have the same code so no need to write them again in each file I change x
<template>
<p>Hello from X component</p>
</template>
<script>
export default {};
</script>
and finally web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Back\DashboardController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
// Call main path
Route::get('/', function () {
return view('app');
});

Title tag change in vuejs

<title>Laravel</title>
I use following
/ In app.js
import VueMeta from 'vue-meta'
Vue.use(VueMeta)
// in vue file
<template>
<div>
</div>
</template>
<script>
export default {
metaInfo: { title: 'Dashboard' },
};
</script>
It's change document title, not actual title tag (Source Code).
i want to change title also in source-code.(Ctrl+U);
You can use
document.title = 'Dashboard'

vuejs-laravel js not working after component switching

I have a JS script declared on my laravel view, below the app.js containing all the vuejs components.
In this script I have elements like charts or a script allowing me to change the monthly price to annual.
And when I switch component, the js doesn't load, while when I refresh the page, it works.
There's probably an option I don't know, which would avoid that?
Thank you in advance.
<!doctype html>
<html lang="en">
<head>
<title>Skrap-it</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<link rel="icon" href="/img/favicons/favicon.ico"/>
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
<link rel="stylesheet" href="{{ mix('css/icons.css') }}">
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="{{ mix('js/app.js') }}"></script>
<script src="{{ mix('js/dashboard/scripts.js') }}"></script>
</body>
</html>
My router js file
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import Register from '../components/auth/Register'
import Login from '../components/auth/Login'
import Profile from '../components/dashboard/Profile'
import Apis from '../components/dashboard/Apis'
import Packages from '../components/dashboard/Packages'
import Support from '../components/dashboard/Support'
import Admin from '../components/dashboard/Admin'
import Dashboard from '../components/dashboard/Dashboard'
const routes = [
{ path: '/dashboard', component: Dashboard },
{ path: '/login', component: Login },
{ path: '/register', component: Register },
{ path: '/profile', component: Profile },
{ path: '/packages', component: Packages },
{ path: '/support', component: Support },
{ path: '/admin', component: Admin },
{ path: '/apis', component: Apis },
]
const router = new VueRouter({
routes,
hashbang: false,
})
export default router
My app.js file
import Vue from 'vue'
import router from './Router/router'
import '../../public/css/dashboard/main.css';
import '../../public/css/custom.css';
window.Vue = require('vue');
const app = new Vue({
el: '#app',
router
});
And I switch to another component with router link to="my_component"

Routing on Vue with SSR and Laravel

I am learning Vue and got stuck trying setup it as full front-end with Laravel, on my scenario I already have made an personal blog for test using Laravel with Blade engine and some components of Vue and seems work fine.
I am trying get on next level, removing Blade and letting Laravel as API backend and setup Vue as full front end with SSR, the basic setup works, I mean I can call Vue, render it using SSR with node or PHPv8, the problem I am having is on route systems, thinking as blade way I can't archive same result, on blade I use an default layout as master and import it for every post, page, blog, etc...
Example:
resources/views/layouts/master.blade
<!DOCTYPE html>
<html dir="ltr" lang="{{ app()->getLocale() }}">
<head>
#include('partials._head')
</head>
#if(View::hasSection('body')) {{-- Load Custom Body --}}
<body #section('body')>
#else
<body>
#endif
#yield('content')
#include ('partials._javascripts')
#section('scripts')
</body>
</html>
So I call a dynamic head per page / post, a dynamic content, an basic javascripts (bootstrap, vue, fontawesome, etc...) and custom 'scripts' per page / posts.
Using the librarie:
https://github.com/spatie/laravel-server-side-rendering
I can get SSR working with node or PHPv8, but the vue-route never call the desired page, my setup is:
resources/assets/js/app.js
import Vue from 'vue';
import App from './layouts/App';
import axios from 'axios';
import store from './store';
import router from './router';
import navbar from './components/navbar';
import posts from './components/posts';
import sidebar from './components/sidebar';
import footer from './components/footer';
import BlogIndex from './views/blog/BlogIndex';
export default new Vue({
store,
router,
navbar,
posts,
sidebar,
footer,
BlogIndex,
render: h => h(App),
});
resources/assets/js/entry-client.js
import app from './app';
app.$mount('#app');
resources/assets/js/entry-server.js
import app from './app';
import renderVueComponentToString from 'vue-server-renderer/basic';
app.$router.push(context.url);
renderVueComponentToString(app, (err, html) => {
if (err) {
throw new Error(err);
}
dispatch(html);
});
resources/assets/js/router.js
// router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './components/Home';
import BlogIndex from './views/blog/BlogIndex';
Vue.use(VueRouter);
const routes = [
{ path: '/', name: 'home', component: Home },
{ path: '/blog', name: 'blog', component: BlogIndex },
];
export default new VueRouter({
mode: 'history',
routes,
});
resources/assets/js/store.js
import Vue from 'vue';
import uniq from 'lodash/uniq';
import Vuex, { Store } from 'vuex';
Vue.use(Vuex);
export default new Store({
state: {
},
getters: {
},
mutations: {
},
});
resources/assets/js/views/blog/BlogIndex.vue
<template>
<div class="container">
<navbar></navbar>
<posts></posts>
<sidebar></sidebar>
<footer></footer>
</div>
</template>
<script>
export default {
name: "BlogIndex",
components: {
}
}
</script>
<style scoped>
</style>
app/Http/Controllers/VueSSRController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Routing\Route;
class VueSSRController extends Controller
{
public function __invoke()
{
return view('layouts.vue');
}
}
resources/views/layouts/vue.blade.php
<!DOCTYPE html>
<html dir="ltr" lang="{{ app()->getLocale() }}">
<head>
#section('extrajavascripts'){{ asset('js/scripts.min.js') }}#endsection
#include('partials._head')
</head>
#if(View::hasSection('body')) {{-- Load Custom Body --}}
<body #section('body')>
#else
<body>
#endif
{{-- Begin of Vue SSR --}}
{!! ssr('resources/assets/js/server_bundle.min.js')
// Share the packages with the server script through context
//->context('packages', $packages)
// If ssr fails, we need a container to render the app client-side
->fallback('<div id="app"></div>')
->render() !!}
{{-- End of Vue SSR --}}
#include ('partials._javascripts')
#section('scripts')
#show
</body>
</html>
/resources/assets/js/layouts/App.vue
<template>
<div id ="app">
{{ message }}
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
message: 'SSR working.'
}
}
}
</script>
<style scoped>
</style>
So SSR works fine, the problem is the resources/assets/js/router.js is not loading the resources/assets/js/views/blog/BlogIndex.vue, the url/blog works, but the component rendered is always the /resources/assets/js/layouts/App.vue.
Someone would point what I am missing setup please?
Thanks in advice!!!
You should place <router-view></router-view> where you want the router to load. I think in your case its below {{message}} in App.vue

Angular2 in visual studio 2017 : run error (Resource not found)

I followed this: https://www.codeproject.com/Articles/1181888/Angular-in-ASP-NET-MVC-Web-API-Part
Error:
My URL - - - > http://localhost/home
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its
dependencies) could have been removed, had its name changed, or is
temporarily unavailable. Please review the following URL and make
sure that it is spelled correctly.
Requested URL: /home
Version Information: Microsoft .NET Framework Version:4.0.30319;
ASP.NET Version:4.7.2110.0
systemjs.config.js
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
'app': 'app',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: 'main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
appcomponent
import { Component } from "#angular/core"
#Component({
selector: "user-app",
template: `
<div>
<nav class='navbar navbar-inverse'>
<div class='container-fluid'>
<ul class='nav navbar-nav'>
<li><a [routerLink]="['home']">Home</a></li>
</ul>
</div>
</nav>
<div class='container'>
<router-outlet></router-outlet>
</div>
</div>
`
})
export class AppComponent {
}
app.routing
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './Components/home.component';
const appRoutes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
app.module
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
_layout.cshtml
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
<script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.js"></script>
<script src="/node_modules/systemjs/dist/system.src.js"></script>
<script src="/systemjs.config.js"></script>
<script src="../node_modules/angular2/bundles/router.dev.js"></script>
<script>
System.import('app/main.js').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<div class="container body-content">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</body>
</html>
Need support please
in your systemjs.config.js change 'npm:': 'node_modules/' to 'npm:': '/node_modules/'
No issues in the code. All good. I was requesting a wrong url.
Also one small change in system.config.js
Instead of 'npm:': 'node_modules/', we need to use 'npm:': '/node_modules/'

Resources