Failed to resolve component: router-link and router-view - laravel

router-view and router-link components cannot be resolved in my app
I don't know what the problem is
attached the app code
it's a home page app with something like a navbar to route to the vue components like states
App\resources\js\router.js
import States from './components/States.vue'
import Cities from './components/Cities.vue'
import Areas from './components/Areas.vue'
import Addresses from './components/Addresses.vue'
const router =createRouter({
history:createWebHistory,
routes :[
{
name:'states',
path:'/states',
Commponent: States
},
{
name:'cities',
path:'/cities',
Commponent: Cities
},
{
name:'areas',
path:'/areas',
Commponent: Areas
},
{
name:'addresses',
path:'/addresses',
Commponent: Addresses
}
]
})
export default new VueRouter({
router
});
App\resources\js\app.js
import App from './components/App.vue'
import router from './router'
import VueAxios from 'vue-axios'
import axios from 'axios'
const app = createApp(App)
app.use(VueAxios,axios,router)
app.mount('#MyApp')
App\resources\js\components\App.vue
<div class="container">
<h2>welcome to vue</h2>
<div class="navbar-nav">
<router-link to="/states">States</router-link>
<router-link to="/cities">Cities</router-link>
<router-link to="/areas">Areas</router-link>
<router-link to="/addresses">Addresses</router-link>
</div>.
<router-view />
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
C:\Users\Kareem\App\resources\js\components\States.vue
<h3>welcome to states component</h3>
</template>
<script>
export default {
}
</script>
<style>
</style>

Try like this for Vue3:
import { createApp } from "vue";
createApp(App)
.use(VueAxios, axios)
.use(router)
.mount('#MyApp')

Related

Router-view not loading contents, failed to mount template

I am new to Laravel and Vue Js. I am facing an issue and I am not being able to figure out what the exact problem is.
app.blade.php
<body>
<v-app id="app">
<example-component/>
</v-app>
<script src="{{ asset('js/app.js') }}"></script>
</body>
app.js
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
import vuetify from './vuetify';
import router from './router';
import Example from './components/ExampleComponent';
new Vue({
el: '#app',
router,
vuetify
});
ExampleComponent.vue
<template>
<div>
<v-content>
<v-container>
<v-btn color="primary" link to="/foo">Foo</v-btn>
<v-btn color="primary" link to="/bar">Bar</v-btn>
</v-container>
<router-view></router-view>
</v-content>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify';
Vue.use(Vuetify)
export default new Vuetify({
})
router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
const foo = {templates: '<v-alert type="success">I am Foo</v-alert>'}
const bar = {templates: '<v-alert type="success">I am Bar</v-alert>'}
Vue.use(VueRouter)
const routes = [
{
path: '/foo',
component: foo,
},
{
path: '/bar',
component: bar,
}
]
export default new VueRouter({
routes
})
It is giving me this error in the console:
app.js:23169 [Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <Anonymous>
<VContent>
<ExampleComponent> at resources/js/components/ExampleComponent.vue
<VApp>
<Root>
My buttons are not loading the router-view. Also, I would like to know what is the difference between registering components using import and Vue.component? Please help me.
It looks like there is a typo. Change:
const foo = {templates: '<v-alert type="success">I am Foo</v-alert>'}
const bar = {templates: '<v-alert type="success">I am Bar</v-alert>'}
to
const foo = {template: '<v-alert type="success">I am Foo</v-alert>'}
const bar = {template: '<v-alert type="success">I am Bar</v-alert>'}

Vuejs register component issue in laravel

I registered App.vue as the main component in Vue.js but when I use it in Laravel blade I get this console error
[Vue warn]: Unknown custom element: <app> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
this is my code in app.js
require('./bootstrap');
import Vue from 'vue';
import VueRouter from 'vue-router';
import Vuex from 'vuex';
import routes from './routes'
import App from './App'
Vue.use(VueRouter);
Vue.use(Vuex);
const router = new VueRouter({
routes,
mode: history
});
Vue.config.devtools = true;
new Vue({
router,
render: h => h(App)
}).$mount('#app');
and my blade
<div id="app">
<App></App>
</div>
<script src="{{ asset('js/app.js') }}"></script>
this is the code I write in App.vue
<template>
<div class="app">
<h1 class="display-4">Hello World from App.vue</h1>
<router-view />
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import App from './views/App'
import Hello from './views/Hello'
import Home from './views/Home'
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/hello',
name: 'hello',
component: Hello,
},
],
});
then in your blade file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue SPA</title>
</head>
<body>
<div id="app">
<app></app>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
also make sure to add this route
Route::get('/{any}', 'SpaController#index')->where('any', '.*');
You can register components like this:
Vue.component("Name", require("./components/Name.vue").default);
app.js:
require('./bootstrap');
import Vue from 'vue';
import VueRouter from 'vue-router';
import Vuex from 'vuex';
import routes from './routes'
import App from './App'
Vue.use(VueRouter);
Vue.use(Vuex);
const router = new VueRouter({
routes,
mode: history
});
Vue.config.devtools = true;
//import components
Vue.component(
'app',
require('./components/App.vue').default);
new Vue({
router,
render: h => h(App)
}).$mount('#app');

Vue Component rendered twice in Laravel 5.8

Working on my first SPA with laravel, vue, vuex, & vue-router. I have a MainApp.vue(to to house the whole app), Header.vue, and a Dashboard.vue component. The Header.vue is being rendered twice in the browser.
//MainApp.vue
<template>
<div id="main">
<Header />
<div class="content">
<router-view></router-view>
</div>
</div>
</template>
<script>
import Header from './Header.vue'
export default {
name: 'main-app',
components: {
Header
}
}
</script>
The app.js
require('./bootstrap');
import Vue from 'vue';
import VueRouter from 'vue-router';
import Vuex from 'vuex';
import {routes} from './routes';
import MainApp from './components/MainApp.vue';
import Header from './components/Header.vue';
Vue.use(VueRouter);
Vue.use(Vuex);
const router = new VueRouter({
routes,
mode: 'history'
});
const app = new Vue({
el: '#app',
router,
components: {
MainApp,
Header
}
});
the body of the welcome.blade.php
<body style="font-family: 'Rajdhani', sans-serif;">
<div id="app">
<main-app />
</div>
<!-- Scripts -->
<script async src="{{ mix('js/app.js') }}"></script>
<script src="{{ asset('js/jquery-3.3.1.min.js') }}" ></script>
<script src="{{ asset('js/popper.min.js') }}" ></script>
<script src="{{ asset('js/bootstrap.min.js') }}" ></script>
<script src="{{ asset('js/mdb.min.js') }}" ></script>
</body>

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

VueJS Router 'Failed to mount component: template or render function not defined.'

I'm following this video: https://laracasts.com/series/learn-vue-2-step-by-step/episodes/26?autoplay=true
My initial problem is described here, but that was resolved. I include it here so you can see what steps I've taken so far.
Now, I'm getting this warning: [Vue warn]: Failed to mount component: template or render function not defined.
A warning is not so bad, but the router-view is not showing up. That is, there is nothing showing up below the Home and About links.
master.blade.php
<!doctype html>
<html lang="en">
<head>
<title>My App</title>
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<div id="app">
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-view></router-view>
</div>
<script src="/js/app.js"></script>
</body>
</html>
Home.vue
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Home Page</div>
<div class="panel-body">
I'm an example component!
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
Any help would be appreciated.
Thanks!
[Edit 1]
resources/assets/js/app.js
import './bootstrap';
import router from './routes';
new Vue({
el: '#app',
router
});
resources/assets/js/bootstrap.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
window.Vue = Vue;
Vue.use(VueRouter);
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
[Edit 2]
resources/assets/js/routes.js
import VueRouter from 'vue-router';
let routes = [
{
path: '/',
component: require('./views/Home.vue')
}
];
export default new VueRouter({
routes
});
Ah! Thanks to TheFallen's questions, I see my problem. Here's what my routes.js file should look like:
import VueRouter from 'vue-router';
import Home from './views/Home.vue';
let routes = [
{
path: '/',
component: Home
}
];
export default new VueRouter({
routes
});

Resources