Vue.js unknown custom element with Laravel (Have already checked other answers) - laravel

My app.js
require('./bootstrap');
window.Vue = require('vue');
import Vue from 'vue'
import Buefy from 'buefy'
Vue.use(Buefy)
// Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('edit-delete-dropdown', require('./components/Dropdown.vue').default);
Vue.component('flash-message', require('./components/FlashMessage.vue').default);
Vue.component('store-create-form', require('./components/StoreCreateForm.vue').default);
const app = new Vue({
el: '#app'
});
My StoreCreateForm.vue
<template>
<section>
<h1 class="title"> Create a new store </h1>
<form :action="createRoute" method="post" role="form">
<input type="hidden" name="_token" :value="csrfToken">
<b-field label="Name">
<b-input placeholder="Store Name" icon-pack="fas" icon="store">
</b-input>
</b-field>
<b-field label="Address">
<b-input placeholder="Store Address" icon-pack="fas" icon="location-arrow">
</b-input>
</b-field>
<b-field label="Description">
<b-input type="textarea" placeholder="Store Description" icon-pack="fas" icon="info-circle">
</b-input>
</b-field>
<b-field>
<button type="submit" name="button" class="button is-primary"> Create </button>
<a class="button is-light" :href="previousUrl"> Cancel </a>
</b-field>
</form>
</section>
</template>
<script>
export default {
props: {
createRoute: String,
csrfToken: String,
previousUrl: String,
}
}
</script>
The story is that I use the element in another blade file:
<store-create-form
create-route="{{ route('users.stores.store', auth()->user()) }}"
csrf-token="{{ csrf_token() }}"
previous-url="{{ url()->previous() }}">
</store-create-form>
and Vue gives me the warning
**[Vue warn]: Unknown custom element: <store-create-form> - did you register the component correctly? For recursive components, make sure to provide the "name" option.**
and doesn't display the component even though I can use the other two components 'edit-delete-dropdown' and 'flash-message' in my application. I also run npm run watch to compile files when there is a change.
I've already checked other answers on StackOverflow and other forums but seems like nothing works.
Any thoughts on this hassle?
Your help will be appreciated.
// Updated:
I think the problem is something with Laravel Mix. I tried changing something in other components and the notification from Mix is 'Build successfully' but it doesn't change in the view (it still worked just fine yesterday)
Just disable cache in the Network tab (F12) and everything works!
Thank you for all your help!

You need to give your component a 'name'
<script>
export default {
name: 'store-create-form'
props: {
createRoute: String,
csrfToken: String,
previousUrl: String,
}
}
</script>

Related

How to configure Croppie for vue 3 in laravel 8?

In a vue page I added a ImageUpload component, following this tutorial: https://www.youtube.com/watch?v=kvNozA8M1HM
It works more or less. No errors, but it only shows my image and a ruler. I can zoom using the ruler, but it does not show boundaries, circle etc. It is completely different from the example in the tutorial...
It is buggy, so to say.
<template>
<div class="Image-Upload-wrapper Image-upload">
<p>
This is image upload wrapper component
</p>
<div id="croppie"> </div>
</div>
</template>
<script>
// uitleg over Croppie::https://www.youtube.com/watch?v=kvNozA8M1HM
import Croppie from 'croppie';
export default {
props:[
'imgUrl'
],
mounted(){
this.image = this.imgUrl // als component is mounted, this.image definieren, en daartmee croppie in..
this.setUpCroppie()
},
data(){
return{
image:null,
croppie:null
}
},
methods:{
setUpCroppie(){
let el = document.getElementById('croppie');
this.croppie = new Croppie(el, {
viewport:{width:200,height:200,type:'circle'},
boundary:{ width:220,height:220},
showZoomer:true,
enableOrientation: true
});
this.croppie.bind({
url:this.image
});
}
}
}
</script>
Is placed in parent as follows:
template>
<div>
<h2>Cards 1</h2>
<div class="form-group">
<input type="text" class="form-control" :placeholder="card.title" v-model="card.title">
</div>
<div class="form-group">
<textarea class="form-control" :placeholder="card.description" v-model="card.description">
</textarea>
</div>
<div id="preview" v-if="url" >
<h4> Preview</h4>
<ImageUpload :imgUrl="url"></ImageUpload>
<!-- <img class="img-circle" style="width:150px" :src="url" /> -->
</div>
<input type="file" v-on:change="onFileChange" ref="fileUpload" id="file_picture_input">
<button #click="editCard(currentSpelerCard)" class="btn btn-warning m-1" style="width:100px;color:black"> Save Card </button>
</div>
</template>
In my package.json I have:
"croppie": "^2.6.5",
in webpack mix I have:
mix.js('resources/js/app.js', 'public/js')
mix.vue();
mix.sass('resources/sass/app.scss', 'public/css');
I have a feeling that something is wrong with the installation of croppie.
Does anyone know what could be the problem here?
Googloing on I found the remark:
"#Since this package also depends on croppie.css you have to import it in your app.js import 'croppie/croppie.css'"
I added the following line to bootstrap.js:
import 'croppie/croppie.css';

2 way binding with Vue3 Inline template (using slots) in laravel blade template files

In Vue3, inline-templates were depreciated and now slots are used. Is it possible to have 2-way binding of variables for Vuejs components written in blade templates?
I want to have 2-way binding for Vue components that's written inline with blade templates. Although I know I can pass data like <example-component name="Hello World"> It is a ton of work to add props everywhere.
Vue recommends using slots as a inline-template replacement since it got removed in v3, however, that documentation makes no sense. I've got the components displayed using the code below. It's a dead simple text field + paragraph to display the name.
home.blade.php (Removed unnecessary HTML for brevity)
<div>
<h1>Dashboard</h1>
<example-component>
<div class="container">
<input v-model="name" placeholder="Change Name"/>
<p> Name is #{{ name }} </p>
</div>
</example-component>
</div>
example-component.vue
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return {
name: 'hi',
}
}
}
</script>
Unfortunately, this does not work, the name doesn't start as 'hi' and doesn't update when changing the textfield. When I try something like <slot :name=name></slot>. Which I believe would pass the name into the slots section, the component gets rendered for a second before disappearing.
Is having 2-way binding with vue variables in blade templates even possible? Any help is appreciated.
Vue: 3.0.5
Laravel: 8.29.0
Is there a reason you're storing the data in the child component? The reactivity design works by passing props down and emitting events up, even though (unfortunately) the reactivity is not maintained when passing a variable up to the parent component. Seems a little counter intuitive, but I might be missing something in what you're trying to create.
It will, however, work if you put the data into the app instead of the component.
// app
const app = Vue.createApp({
data() {
return {
name: 'hi',
}
}
})
// component
app.component('example-component', {
template: `
<div>
<slot></slot>
</div>`,
})
app.mount("#app");
<script src="https://unpkg.com/vue#3.0.5/dist/vue.global.prod.js"></script>
<div id="app">
<h1>Dashboard</h1>
<example-component>
<div class="container">
<input v-model="name" placeholder="Change Name"/>
<p> Name is #{{ name }} </p>
</div>
</example-component>
</div>
<!--

Vuejs component not registering with laravel

I know this question is being asked several times, but I couldn't find any solution to my problem.
I have two vue components on my laravel project. The first one is the laravel default component called "ExampleComponent.vue" and the second one is my own new component called "multi.vue".
I use them in a section.blade.php file like below:
#extends('layouts.app')
#section('content')
<example-component></example-component>
<multi></multi>
#endsection
but only the "example-component" works and for the "multi" component, it gives me the following error:
Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
here is my app.js code:
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('multi', require('./components/multi.vue').default);
const app = new Vue({
el: '#app',
});
Here is my components codes:
ExampleComponent.vue:
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
And my multi.vue:
<template>
<div>
I am multi component!
</div>
</template>
<script>
export default {
mounted() {
console.log('multi mounted.')
}
}
</script>
<style>
</style>
And the route is:
Route::get('/section',function(){
return view('section');
});
For solving this problem, all you need to do is to run "run npm watch".
After running that command, it will recomplie your vue code whenever you make a change in your code and save it.
Keep it in a separate terminal, and run "php artisan serve" in another terminal.
From https://v2.vuejs.org/v2/style-guide/#Multi-word-component-names-essential:
Component names should always be multi-word, except for root App
components, and built-in components provided by Vue, such as
<transition> or <component>.
This prevents conflicts with existing and future HTML elements, since
all HTML elements are a single word.

How to use v-model within Laravel

Below is my app.js file. When using v-model, and NOT v-modal, do I need to import anything in the app.js file or download anything via npm? I have already ran npm install. The template is working fine and all normal vue functionality is working, I am only stuck when it comes to v-model. v-model is not working. The email is not appearing in the body when I use v-model.
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
Vue.component('formtemp', require('./components/formtemp.vue').default);
const app = new Vue({
el: '#app',
});
Vue Component
<template>
<div class="form-group">
<label for="email">Email</label>
<input
v-model='email'
type="text"
id="email"
placeholder="email"
class="form-control"
>
<h1>Email: {{email}}</h1>
</div>
</template>
<script>
export default {
data() {
return {
email: ''
}
},
}
</script>
I’m guessing formtemp component generates a form element.
I think formtemp is not including the Example component and as such the input elements it’s generating are outside the form element and not sent when making the HTTP call.
Including the Example component inside your form component should fix it.

Vue.js won't update it's place to edit

I've been having troubles with my new side-project. Saw Vue.js, thought it was cool and gave it a try.
This is where I insert my new blog post:
<input class="form-control" placeholder="Title" v-model="header" name="title" type="text" value="">
And this is where it should update:
<div id="create_post" class="site-heading">
<h1>New post</h1>
<hr class="small">
<span class="subheading"></span>
</div>
This is my javascript file:
new Vue({
el: '#create_post',
data: {
header: 'New post',
subheader: '...'
}
});
If i put input below the place it should update, it won't work but if the input comes first, then it works like a charm.
How should I continue?
I told that in my comment i posted, and v-model has to be without .lazy ending to make it update in real time.
So the whole thing has to be in div #app and model has to be like v-model="header", not v-model="header.lazy"
This is hat you need:
new Vue({
el: '#app',
data: {
header: 'Post Title'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<div id="app">
<input v-model="header" name="title" type="text" value="">
<h1>{{ header }}</h1>
</div>
What you are doing wrong is that, your vue element is create_post and input is out of that element, so Vue can't recognise v-model on that

Resources