Vue Component rendered twice in Laravel 5.8 - laravel

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>

Related

My Vue root file/component is not showing up in Laravel

I'm following this simple Crud tutorial for Vue + Laravel and everything in Laravel part seems fine (from creating controllers & models) seems fine but I can't make vue show up in Laravel welcome blade. Here's my code:
app.js file
require('./bootstrap');
window.Vue = require('vue');
import App from './App.vue';
import VueAxios from 'vue-axios';
import VueRouter from 'vue-router';
import axios from 'axios';
import { routes } from './routes';
Vue.use(VueRouter);
Vue.use(VueAxios, axios);
const router = new VueRouter({
mode: 'history',
routes: routes
});
const app = new Vue({
el: '#app',
router: router,
render: h => h(App),
});
App.vue file:
<template>
<div class="container">
<h2>Vue app</h2>
<router-view> </router-view>
</div>
</template>
<script>
export default {}
</script>
and this is the 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">
<title>Laravel</title>
<style>
body {
font-family: 'Nunito', sans-serif;
}
</style>
</head>
<body class="antialiased">
<div id="app"> </div>
<script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
<h2>The welcome blade</h2>
</body>
</html>
edit: answer added below, basically followed another tutorial
Looking at the code after composer require laravel/ui and php artisan ui vue I see small change that may affect the execution of code.
Originally the Laravel setup creates window.Vue = require('vue').default;, but your code has window.Vue = require('vue')
Firstly, try this:
<script src="{{ asset('js/app.js') }}" defer></script>
Secondly, you may need a router view element inside the div with id app. I can't say for sure since I don't know your routes. If the change above doesn't solve the problem, add router view like
<div id="app">
<router-view />
</div>
UPDATE
Another thing to try. Remove these lines
import VueAxios from 'vue-axios';
import axios from 'axios';
Vue.use(VueAxios, axios);
because you have axios on bootstrap.js file.
And make sure there is no error message on the console.
So it must have been something wrong with my installation process because I followed another tutorial and now it's working video

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 not being rendered in blade file

So I am trying to build a new Laravel app with Vue. For some reason, the example component that the app comes with works fine, but my own doesn't. Here's my file structure and code:
views/layout/vue.blade.php
<html>
<head>
<title>Skat</title>
</head>
<meta name="csrf-token" content="{{ csrf_token() }}">
<body>
<div id="app">
#yield("content")
</div>
<script src="/js/app.js"></script>
</body>
</html>
resources/views/vue.blade.php this is working fine!
#extends('layouts.vue')
#section('content')
<example-component></example-component>
#endsection
resources/js/components/ExampleComponent.vue
<template>
<div class="container">
some stuff ..
</div>
</template>
<script>
export default {
name: 'example-component',
mounted() {
console.log('Component mounted.')
}
}
</script>
resources/views/home.blade.php this is NOT working :(
#extends('layouts.vue')
#section('content')
<home></home>
#endsection
resources/js/components/Home.vue
<template>
<div class="container-fluid d-flex h-100 flex-column">
test test
</div>
</template>
<script>
export default {
name: 'home',
components: {
}
}
</script>
<style scoped>
...
</style>
routes/web.php
Route::get('/', function () {
return view('vue');
});
Route::get('/home', function () {
return view('home');
});
resources/js/app.js
...
import ExampleComponent from './components/ExampleComponent.vue';
import Home from './components/Home.vue';
const app = new Vue({
el: '#app',
components: {
ExampleComponent,
Home
}
});
I am not getting any errors or anything. I guess somewhere I didn't set it up right, but I'm confused!
Thanks! :)
Don't use components: {} on the root instance. Explicitly declare it with:
Vue.component('example-component', ExampleComponent).
Even better.
const files = require.context('./', true, /\.vue$/i);
files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default));

how to fix Unknown custom element: <router-view>

I import the vue-route to my app.js in my laravel vue website. Sadly, there's an error. Can you please guide me thanks
app.js
require('./bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router'
Vue.use(VueRouter)
let routes = [
{path: '/', component: require('./components/Welcome.vue') }
]
const router = new VueRouter({
mode: 'history',
routes
})
const app = new Vue({
el: '#app',
router,
});
master.blade.php
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<body>
<div id="app">
#yield('content')
</div>
</body
welcome.blade.php
#extends('layouts.master')
#section('content')
<router-view></router-view>
<vue-progress-bar> </vue-progress-bar>
#endsection
The result should be the Welcome.vue will display.
If you use a newer version of Vue.js you should have .default to require('./components/Welcome.vue')
So line 5 would look like this
{path: '/', component: require('./components/Welcome.vue').default }
Stack Overflow: Why need default after require() method in Vue?
As per documentation, you should inject router option to make your whole app router aware.
So you should have something like this:
const app = new Vue({
router
}).$mount('#app')
I think this is duplicate of this.

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