Unknown custom element: <app-home> - did you register the component correctly? For recursive components, make sure to provide the "name" option - laravel

I have this problem but i try some solutions in web but and i can't resolve it: Unknown custom element:
- did you register the component correctly? For recursive components, make sure to provide the "name" option.
The problem appears to be in those fils :
Please I need help as soon as possible
routes.js:
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../components/Home.vue";
import PostDetails from "../components/PostDetails.vue";
Vue.use(VueRouter);
const routes = [{
path: "/",
component: Home,
name: "Home"
},
{
path: "/post/:slug",
component: PostDetails,
name: "postDetails"
}
];
const router = new VueRouter({
routes: routes,
hashbang: false,
mode: "history"
});
export default router;
app.js:
import Vue from "vue";
import VueRouter from "vue-router";
require('./bootstrap');
window.Vue = require('vue');
Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('app-home', require('./AppHome.vue'));
import router from "./routes/routes.js";
const app = new Vue({
el: '#app',
vuetify,
render: h => h(App),
router: router,
});
AppHome.vue:
<template>
<div>
<router-view></router-view>
</div>
</template>
<script>
export default {
};
</script>
Home.vue:
<template>
<div class="container">
<div class="row my-4">
<div class="col-md-8">
<div class="card">
<div class="card-header">Articles</div>
<div
class="card-body"
:key="index"
v-for="(post, index) in posts.data"
>
<div class="media">
<img
:src="post.photo"
class="rounded img-fluid mr-2 shadow-sm"
alt=""
srcset=""
/>
<div class="media-body text-justify">
<router-link :to="post.path">
<h3>{{ index }}:{{ post.title }}</h3>
</router-link>
<p>
<span class="textdefaut">
{{ post.user.name }}
</span>
<span class="text-danger">
{{ post.added }}
</span>
</p>
<p class="lead text-justify">
{{ post.body.substr(0, 200) }}...
</p>
<hr />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
posts: {},
};
},
created() {
this.getPosts();
},
methods: {
getPosts() {
axios
.get("/api/posts")
.then((response) => {
console.log(response.data);
this.posts = response.data;
})
.catch((err) => console.log(err));
},
},
};
</script>
Post Details:
<template>
<div>
Posts details , This shows that the route is really working!!
<router-link to="/Home"><a>Back to the root</a></router-link>
</div>
</telpmate>
<script>
export default {
data () {
return {
message: 'Hoera!!!!'
};
}
};
</script>

If all of your Vuejs components (including AppHome.vue) are in /resources/js/components directory, you must change:
Vue.component('app-home', require('./AppHome.vue'));
by
Vue.component('app-home', require('./components/AppHome.vue'));
...in your app.js
Try to append .default option:
Vue.component('app-home', require('./components/AppHome.vue').default);

Related

Json being displayed instead on Vue component

**ChatController**
am new to laravel and vue i just got this and wanted learn some new skills.
This controller queries a single user from my model called PostRequest i use one-to-one relationship
class ChatController extends Controller
{
public function getMessages()
{
return view('user.message'); //response()->json($contacts);
}
public function get()
{
$email = Auth::user()->email;
$contacts = PostRequest::with('user')->where([['email', $email]])->orderBy('id','DESC')-
>first()->user;
return response()->json($contacts, 200);
}
}
ChatComponent
<template>
<div class="chat-app">
<Conversation :contact="selectedContact" :messages="messages" />
<ContactsList
v-if="contacts"
:contacts="contacts"
/>
</div>
</template>
<script>
import Conversation from './Conversation';
import ContactsList from './ContactsList';
export default {
props: {
user: {
type: Object,
required: true
}
},
data() {
return {
selectedContact: null,
messages: [],
contacts: null
}
},
mounted() {
//console.log('LoggedIn User',this.user);
axios.get('/user/contacts').then((response) => {
// console.log('contact', response.data);
if(this.contacts == undefined){return}
this.contacts = response.data;
}).catch((error) => {
console.log(error.message);
});
},
components: {Conversation, ContactsList}
}
</script>
ContactListComponent
this component will pass my user data into message.blade
<template>
<div class="contacts-list" >
<ul v-for="contact in contacts" :key="contact.id">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quaerat, autem.</p>
<li >
<div class="avatar">
<img :src="contact.user.reqPhoto" :alt="contact.user.name">
</div>
<div class="contact">
<p class="name">{{contact.user.name}}</p>
<p class="email">{{contact.user.email}}</p>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
contacts: {
type: [],
default: null
}
}
}
message blade
this blade file recieves the user data from vue, have tried to view page source nothing is coming in
<section class="inbox">
<div class="container">
<div class="row">
<div class="col-md-8 text-center">
<div class="card">
<div class="card-header">Chat with:</div>
<div class="card-body" id="app">
<chat-component :contacts="contacts"></chat-component>
</div>
</div>
</div>
#include('layouts.sidenav')
</div>
</div>
</section>
web Routes
i also tried using same routes its still returns same json file even after trying different browsers
Route::get('/user/messages', [ChatController::class, ('getMessages')])->name('msg');
Route::get('/user/contacts', [ChatController::class, ('get')]);
app.js
require('./bootstrap');
window.Vue = require('vue').default;
Vue.component('chat-component',
require('./components/ChatComponent.vue').default);
Vue.component("Conversation",
require("./components/Conversation.vue").default);
Vue.component('contact',
require('./components/ContactsList.vue').default);
Vue.component("MessagesFeed",
require("./components/MessageFeed.vue").default);
Vue.component("MessageComposer",
require("./components/MessageComposer.vue").default);
const app = new Vue({
el: '#app',
});

displaying laravel show method on vue component

i have a list of movies am trying to display the details of one movie using the show method
here is my component for all movies
<template>
<div>
<el-row :gutter="10">
<el-col :span="6" v-for="movie in movies" v-bind:key="movie">
<el-card shadow="always" :body-style="{ padding: '0px'} ">
<img v-bind:src="movie.cover_photo" class="image" >
<div style="padding: 14px;">
<div class="bottom clearfix">
<router-link :to="{name:'details',params:{id:movie.id}}">{{movie.title}}</router-link>
<router-view></router-view>
<h4>{{ movie.year }}</h4>
<h4>{{ movie.type }}</h4>
</div>
<div class="block">
<el-rate :max="10" ></el-rate>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
movies: [],
movie:{
id:'',
}
};
},
created(){
this. fetchMovieList();
this.showMovie
},
methods: {
fetchMovieList() {
axios.get('/movies').then(response => {
this.movies = response.data;
})
.catch(error=>console.log(error))
},
showMovie(id){
axios.get('/movies/'+id).then((res)=>{
if(res.data.status==true){
this.movie= res.data.movie;
console.log(res.data.movie)
}else{
alert('No Movie founded with this id')
}
})
.catch((err)=>{alert('error')})
}
}
}
</script>
<style scoped>
.image {
width: 100%;
display: block;
}
</style>
my show method:
public function show($id)
{
$movie=Movie::find($id);
if($movie){
return response()->json(['status'=>true,'movie'=>$movie]);
}else{
return response()->json(['status'=>false]);
}
}
my router on app.js:
const movie=Vue.component('details', require('./components/DetailsComponent.vue').default);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const router=new VueRouter({
mode:'history',
routes:[
{
path:'/movie/:id',
name:'movie',
component:movie
},
],
});
const app = new Vue({
el: '#app',
router,
});
when i click on the router link it just changes the url to the id of the movie but it doesnt show the component with details when i hit the show endpoint with a specific id it returns the movie in json format on the browser
I think your variable of v-for conflict with the same variable of data().
You should try another variable name of v-for.
Something like
<el-col :span="6" v-for="value in movies" v-bind:key="movie">
<el-card shadow="always" :body-style="{ padding: '0px'} ">
<img v-bind:src="value.cover_photo" class="image" >
<div style="padding: 14px;">
<div class="bottom clearfix">
<router-link :to="{name:'details',params:{id:value.id}}">{{value.title}}</router-link>
<router-view></router-view>
<h4>{{ value.year }}</h4>
<h4>{{ value.type }}</h4>
</div>
<div class="block">
<el-rate :max="10" ></el-rate>
</div>
</div>
</el-card>
</el-col>
Hope this helps you: Reacting to Params Changes
Regards,

Laravel 6 + Vue.js Failed to mount component: template or render function not defined

Perhaps someone could help me? I'm trying to create a little chat app from here and I am have trouble displaying the Vue components.
The dev tools console gives me:
Failed to mount component: template or render function not defined.
I am using Laravel 6
Appreciate any help on this one! thanks :)
I have tried deleting the node_modules folder and rebuilding, after adding .default - with no luck.
app.js
require('./bootstrap');
window.Vue = require('vue');
/**
* The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue
* components and automatically register them with their "basename".
*
* Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
*/
const files = require.context('./', true, /\.vue$/i)
files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('chat-messages', require('./components/ChatMessages.vue').default);
Vue.component('chat-form', require('./components/ChatForm.vue').default);
import Vue from 'vue'
const app = new Vue({
el: '#app',
data: {
messages: []
},
created() {
this.fetchMessages();
Echo.private('chat')
.listen('MessageSent', (e) => {
this.messages.push({
message: e.message.message,
user: e.user
});
});
},
methods: {
fetchMessages() {
axios.get('/messages').then(response => {
this.messages = response.data;
});
},
addMessage(message) {
this.messages.push(message);
axios.post('/messages', message).then(response => {
console.log(response.data);
});
}
}
});
and my two components:
ChatForm.vue
<template>
<div class="input-group">
<input id="btn-input" type="text" name="message" class="form-control input-sm" placeholder="Type your message here..." v-model="newMessage" #keyup.enter="sendMessage">
<span class="input-group-btn">
<button class="btn btn-primary btn-sm" id="btn-chat" #click="sendMessage">
Send
</button>
</span>
</div>
</template>
<script>
export default {
props: ['user'],
data() {
return {
newMessage: ''
}
},
methods: {
sendMessage() {
this.$emit('messagesent', {
user: this.user,
message: this.newMessage
});
this.newMessage = ''
}
}
}
</script>
ChatMessage.vue
<template>
<ul class="chat">
<li class="left clearfix" v-for="message in messages" v-bind:key="message">
<div class="chat-body clearfix">
<div class="header">
<strong class="primary-font">
{{ message.user.name }}
</strong>
</div>
<p>
{{ message.message }}
</p>
</div>
</li>
</ul>
</template>
<script>
export default {
props: ['messages']
};
</script>
This might help you to solve your problem, if not just tell me to find new solution. first remove this in your app.js
const files = require.context('./', true, /\.vue$/i)
files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Next, remove also this code, you already imported vue twice.
import Vue from 'vue'

vue components wont load

I try to work with vuejs in laravel, I installed npm vue-router vue-axios but when i try to load my page i get console error like: ReferenceError: CreateCategory is not defined and empty page.
here is my app.js:
require('./bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import VueAxios from 'vue-axios';
import axios from 'axios';
Vue.use(VueAxios, axios);
import App from './App.vue';
Vue.component('CreateCategory', require('./components/CreateCategory.vue'));
Vue.component('DisplayCategory', require('./components/DisplayCategory.vue'));
Vue.component('EditCategory', require('./components/EditCategory.vue'));
const routes = [
{
name: 'CreateCategory',
path: '/categories/create',
component: CreateCategory
},
{
name: 'DisplayCategory',
path: '/',
component: DisplayCategory
},
{
name: 'EditCategory',
path: '/edit/:id',
component: EditCategory
}
];
const router = new VueRouter({ mode: 'history', routes: routes});
new Vue(Vue.util.extend({ router }, App)).$mount('#app');
// const app = new Vue({
// router,
// render: h => h(App)
// });
// const app = new Vue({
// el: '#app'
// });
PS: I read articles about component in router and I already tried with .default that won't work neither they only good of that was i didn't get console error.
UPDATE
my CreateCategory.vue component:
<template>
<div>
<h1>Create A Category</h1>
<form v-on:submit.prevent="addCategory">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Category Title:</label>
<input type="text" class="form-control" v-model="category.title">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Category Status:</label>
<input type="text" class="form-control col-md-6" v-model="category.status" />
</div>
</div>
</div><br />
<div class="form-group">
<button class="btn btn-primary">Add Category</button>
</div>
</form>
</div>
</template>
<script>
export default {
data(){
return{
category:{}
}
},
methods: {
addCategory(){
let uri = 'http://localhost/vuetjd/public/categories';
this.axios.post(uri, this.category).then((response) => {
this.$router.push({title: 'DisplayCategory'})
})
}
}
}
</script>
CreateCategory.vue is a Single File Component.
In there, you must have a export default {}, where {} is actually the Component Object.
What you have to do, is that, you need to import the CreateCategory.vue and then assign it, like so:
import CreateCategory from './components/CreateCategory.vue';
const routes = [
{
name: 'CreateCategory',
path: '/categories/create',
component: CreateCategory
}
];
now this will work.
you have to do the same for DisplayCategory and EditCategory.
I found what is the issue, I'm suppose to run php artisan serve to be able to see my data. if just open my url i'll get blanck page but with serve i get my data as well.

Attempting to load a Vue component and populate it with Ajax json content in Laravel

I am new to Laravel and a complete noob to Vue. I searched many other Laravel/Vue posts but none seemed to be similar enough to get me to a solution. When attempting to load this component on my view I receive the following error
app.js:32654 [Vue warn]: Property or method "features" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
Please let me know what I am missing.
chrome.google.com/webstore/detail/vuejs-devtools/ shows that Vue is loaded
I would like to load data from an ajax call to my vue component. that can be updated on the fly by event handler
App.js
window.Vue = require('vue');
Vue.component('Example', require('./components/Example.vue'));
const app = new Vue({
el : '#app',
});
$(document).ready(function() {
$.ajaxSetup({
headers : {
'X-CSRF-TOKEN' : $('meta[name="csrf-token"]').attr('content')
}
});
})
Example.vue
<template>
<div class="container projects-container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
<h1>I'm an example component!</h1>
<ul class="list-group">
<li class="list-group-item" v-for="feature in features">
{{ feature.properties.name }}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
},
}
</script>
bladefile
<head>
<meta name="csrf-token" content="INMA4kLlG32gfhf4Z3BBGIFxitrVCWzzqgqPfooEj">
// and yes Vue is loaded
</head>
<body>
<div id="app">
<example></example>
</div>
...
<script>
Vue.component('example',{
template: 'Example',
})
//returns the JSON listed below
someOtherObject.addListener('click', function(e) {
$.ajax({
url:json,
method:'GET',
success:function(msg){
app.data = JSON.parse(msg);
}
})
})
</script>
JSON
{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.155083,
33.569672
]
},
"properties":{
"heading":null,
"face":"South",
"status":"1",
"name":"MEADOWLARK ",
"type":"Single Family Home",
"client_id":"26",
"client_name":"Pulte Homes",
"city_name":"French Valley"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.151390,
33.543981
]
},
"properties":{
"heading":null,
"face":"South",
"status":"1",
"name":"Testing Project",
"type":"Single Family Home",
"client_id":"83",
"client_name":"Testing Account",
"city_name":"Temecula Valley"
}
},
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-117.223720,
33.571522
]
},
"properties":{
"heading":null,
"face":"South",
"status":"1",
"name":"Oak Ridge",
"type":"Single Family Home",
"client_id":"98",
"client_name":"Woodside 05S LP",
"city_name":"Beaumont"
}
}
]
}
The features array must be declared either as a prop or part of the component data.
As a prop:
<template>
<div class="container projects-container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
<h1>I'm an example component!</h1>
<ul class="list-group">
<li class="list-group-item" v-for="feature in features">
{{ feature.properties.name }}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
},
props: ['features']
}
</script>
As component data:
<template>
<div class="container projects-container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Example Component</div>
<div class="panel-body">
<h1>I'm an example component!</h1>
<ul class="list-group">
<li class="list-group-item" v-for="feature in features">
{{ feature.properties.name }}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
},
data: function() {
return {features: []}
}
}
</script>
If you use a prop, you'll need to bind the prop in the template. If you use component data, you'll need to update the success callback function in the AJAX request to correctly update the data of the component rather than the app as a whole.
Also, beware of the reactivity caveats for loading new data, as outlined in the docs.
EDIT: Full example solution using component data
Here's a working example using a simplified version of your example component. Note that to do this I used the ref attribute so that the component could be addressed directly. Using refs is described in the docs as an "escape hatch" that should only be used when strictly necessary. A better pattern might be an external store, such as Vuex.
Vue.component( "example", {
template: '<div><h1>Example Component!</h1><ul v-if="features.length"><li v-for="feature in features">{{ feature.name }}</li></ul></div>',
data: function() {
return { features : [] }
}
});
var app = new Vue( { el: '#app' });
//A function to represent the AJAX callback
var doMockAjax = function() {
var mockData = [{name: 'One'},{name: 'Two'},{name: 'Three'}];
app.$refs.example.features = mockData;
}
document.getElementById('load-data').addEventListener('click', function(e) {
//This simulates the ajax callback by populating the array asynchronously
setTimeout(doMockAjax,1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<example ref="example"></example>
</div>
<button id="load-data">Load</button>

Resources