How to use form mask in Laravel with Vue - laravel

I'm trying to use mask on Form with Laravel and VueJS using https://vuejs-tips.github.io/vue-the-mask/, I'm new to Vue so I looked for some way to use mask, I ended up finding this lib. However, I do not know how to use the example of the site since it does not show a complete example, just snippets of code.
Displays the second error:
SyntaxError: import declarations may only appear at the top level of a module inscriation: 62: 8
[Vue Warn]: Error compiling template:
[Vue Warn]: Failed to resolve directive: mask
(found in )
I added the code in the blade.php
<script src = "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"> </ script>
<script>
// Local Directive
import {mask} from 'vue-the-mask'
export default {
directives: {mask}
}
</ script>
<template>
<input type = "tel" v-mask = "'##/##/####'" />
</ template>

You can't do import in native (browser) JS, you need to use laravel mix or webpack (or any other bundler)
easiest solution: laravel-mix
npm install laravel-mix --save
then open (or create webpack.mix.js file), and type this (of course you need to specify your own path)
var mix = require('laravel-mix');
mix.js('/resources/path_to_input_javascript', '/public/path_to_resulting_javascript')
In your input file you create simple vue instance (and import your component)
import Vue from 'vue';
import mask from 'path_to_component.vue'
var app = new Vue({
el: "#root", //root element name
components: {'x-mask': mask}
});
and in your component you put the code:
<script>
// Local Directive
import {mask} from 'vue-the-mask'
export default {
directives: {mask}
}
</script>
<template>
<input type = "tel" v-mask = "'##/##/####'" />
</template>
It's not that complex, once you get used to it. You should read/watch about bundlers.

Related

Using vue2-google-maps with Laravel 9: The map is empty

My Laravel 9 project uses Vue 2.6 and Vuetify.
As I need to display a Google map, I decided to use vue2-google-maps package. My Google Maps is displaying as blank (though it does take the proper width and height on the page)
This is my app.js file:
import Vue from 'vue'
import vuetify from './plugins/vuetify' // path to vuetify export
import * as VueGoogleMaps from 'vue2-google-maps'
Vue.use(VueGoogleMaps,{
key:'My_GOOGLE_API_KEY',
libraries: 'places',
})
new Vue({
vuetify,
}).$mount('#app')
The is my blade file
<template>
<div class="map">
<p>Google Map</p>
<gmap-map
:center="{
lat: 47.2736,
lng: 16.0843
}"
:zoom = "7"
style="width:100%; height: 280px;"
>
</gmap-map>
</div>
</template>
Am I doing something wrong? Please advise how to fix the issue or if there is any suggestion to use some-other package.
Thanks.

Laravel 7 and VueJs Vue Multiselect Noob Question

I am a totally noob at laravel and npm and vuejs things.
I made a new Laravel Project and instead of playing around with jquery I want to learn how to use vuejs.
I ran against a wall today :( trying 2 days to get this Multiselect (https://vue-multiselect.js.org/#sub-select-with-search) running on my project.
I think I am missing some basics ...
What I've done:
ran on terminal npm install vue-multiselect
created in resources/js/comonents/Multiselect.vue
pasted this code in /Multiselect.vue:
<template>
<div>
<multiselect
v-model="selected"
:options="options">
</multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
data () {
return {
selected: null,
options: ['list', 'of', 'options']
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
added to my app.js in resources folder:
- import Multiselect from "vue-multiselect";
- Vue.component('v-multiselect', require('./components/Multiselect.vue'));
- const app = new Vue({
- el: "#app",
- data: {
- users: '',
- firmas: '',
}});
and in my blade file I used:
<v-multiselect></v-multiselect>
So far ... so good
npm run dev and refreshed the page.
Error:
index.js:133 [Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <VMultiselect>
<Root>
so I have two questions is this the correct way to implement external vuejs components inte Laravel ?
and what If it is the right way am I doing wrong - at which points???
Thank you all out there to help me to learn ...
I'm glad you got your code working! To answer your question, it looks like you're using a mix of the external component you're importing and your own custom component which uses that component which may be what is confusing you a little bit.
When you do the following:
import Multiselect from "vue-multiselect";
inside your app.js file, you are importing an external component globally. When you place that import inside of a component, you are importing the external component for use within that component only. In your current code you've posted, you are importing it both globally and within your component.
If you are registering a component globally (within the element id assigned to the vue instance), you can register it like this within your app.js file:
import Multiselect from "vue-multiselect";
Vue.component('multiselect', Multiselect);
Then in your components, you will not have to import it again, but simply use it like this:
<template>
<div>
<multiselect v-model="selected" :options="options" placeholder="Select one" label="name" track-by="name"></multiselect>
</div>
</template>
<script>
export default {
data() {
return {
selected: null,
options: ['one','two','three'],
}
},
}
</script>
You would also be able to use this component in your blade since it is defined within your app.js file.
However with the setup you're using now, your fix of:
Vue.component('v-multiselect', require('./components/Multiselect.vue').default);
is not actually registering the external component. You are registering YOUR component.
So to answer your question, yes, you've taken an external component where you can make your custom component and easily add reusable content around it which is perfectly valid use, but you could either remove the extra import of Multiselect in your app.js file, or import the Multiselect external component globally, like I mentioned above.
Update:
Found the solution for my problem:
in my app js there was the error!
Vue.component('v-multiselect', require('./components/Multiselect.vue').default);
I registered the component wrong :(
So second question is answered :)
But do you guys do it the same way? or I am completly wrong implementing external commponets into laravel?
I don't want to use vueex or vuerouter for now ... I need to learn laravel itself ... afterwards I know how Laravel works I will use vuerouter ... for my projects ...
So sorry for the long text - but needed to explain a little bit more about the situation - thnaks for reading guys!
Thank you very much Sawyer,
I got it, I thought :(
I want to use this multiselect component muptliple times in my page.
So I removed the extra import in my app.js - saw it in phpstorm that it was unused but didn't know why :) - now I know.
What I have so far:
hit me if I am wrong :)
in app.js: (registering my own component)
Vue.component('v-multiselect', require('./components/Multiselect.vue').default);
added Multiselect.vue to my components folder in laravel with this src:
<template>
<div>
<multiselect v-model="value" :options="options"></multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
// register globally
Vue.component('multiselect', Multiselect)
export default {
// OR register locally
components: { Multiselect },
data () {
return {
value: null,
options: ['option1','option2','option3']
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
and in my blade file:
<v-multiselect :options="['one','two','three']" ></v-multiselect>
I get no errors at all from vuejs butit isn't working as it should:
How do I overwrite the options array from my blade file ? As I saw on the documentation "options" is a prop of the component so why am I getting as select the predefined option array ['option1','option2','option3'] and not the array from the blade file:['one','two','three'] am I missing a shortcut or something else?? Thanks a lot for your patience ...
If you can tell me where to read about it - except the docs of vuejs - I think this will help me a lot!

Vue Component not showing text when called from blade.php file

I have a basic vue 2.6.11 component that lives in a laravel 6 application. It lives at resources/js/components. I create a basic component and then in my app.js file I have vue imported and I define my vue component. Then in my app.blade.php I use the vue component but the text within my <template><div>Text here</div></template> does not appear on the screen. The <h1> text appears but not the vue component text. I looked at other posts but the vue versions other questions on here use are 2-3 years too old and don't apply. Any help is appreciated, thanks.
TableDraggable.vue
<template>
<div>
<h1>Test Text</h1>
</div>
</template>
<script>
export default {
mounted() {
console.log('this component has been mounted');
}
}
</script>
What I am using in my app.blade.php file
<h1>This is a test to see if VUE is working</h1>
<table-draggable></table-draggable>
app.js snippet
//Bring in VUE and vue draggable
window.Vue = require('vue');
import VueDraggable from 'vuedraggable';
Vue.component('table-draggable', require('./components/TableDraggable'));
In app.js try the following:
...
window.Vue = require('vue');
import VueDraggable from 'vuedraggable';
Vue.use(VueDraggable);
import TableDraggable from './components/TableDraggable';
Vue.component('table-draggable', TableDraggable);
const app = new Vue({
el: '#app',
data() {
return {};
},
});
...
Then in some parent element of where you are using your component, make sure it has an id of app. eg:
<div id="app">
<h1>This is a test to see if VUE is working</h1>
<table-draggable></table-draggable>
</div>
This is a basic example of getting vue working on your site, and not necessarily the best way to be structuring your assets depending on your needs. The biggest considerations about how to structure these are how bulky your assets will become if you include everything in app.js.

Importing a JavaScript class into a Vue single file component using Laravel Mix

I'm writing a Vue single page component in my project which is bundled using Laravel Mix. I want to extract some logic out into its own class so that it can be easily re-used across other components (but this isn't logic that should be a Vue component itself).
I made a new class and put it in TimeRangeConverter.js, in the same directory as my Vue component.
export default class TimeRangeConverter {
static getFromTimestamp() {
return 1;
}
}
And in my component, I'm importing it as I think I normally would:
<template>
<div>
Example component
</div>
</template>
<script>
import './TimeRangeConverter';
export default {
mounted() {
console.log(TimeRangeConverter.getToTimestamp());
}
}
</script>
However Vue is throwing an error saying ReferenceError: TimeRangeConverter is not defined.
I'm using the default webpack.mix.js config file that comes with Laravel 5.7:
mix.js('resources/js/app.js', 'public/js');
And in my main app.js file I'm automatically including Vue components with:
const files = require.context('./', true, /\.vue$/i);
files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default));
What's the correct way to import this class into a Vue component for usage?
You should import your class inside your component code using the following syntax :
import TimeRangeConverter from './TimeRangeConverter';

How to import Vue component to script tag?

I have some Vue components (.vue) in my Laravel project, resources\assets\js\components. I want to import the components to a view file .blade.php:
<div id='lol'>
<some-component></some-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<script>
import SomeComponent from '.\resources\assets\js\components\some.vue
new Vue({
el: '#lol'
});
</script>
I got error in console: Uncaught SyntaxError: Unexpected identifier at the import
I don't wanna register the component in app.js
If you don't want to use a compiler, you could use a library such as http-vue-loader, which provides a function to do just that.
Important: The author of the library itself does not recommend to use this library for production environments. Instead, he recommends you to compile your .vue files.
When using the http-vue-loader library, your snippet would look like this:
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
<div id='lol'>
<some-component></some-component>
</div>
<script>
new Vue({
components: {
'some-component': httpVueLoader('./resources/assets/js/components/some.vue')
},
el: '#lol',
});
</script>
Alternatively, you can compile and export your vue component as a library, which you then can add to your project.
To export your component as a library, you first need to create an entry point for your component, for example: 'resources\assets\js\components\index.js'. In this entry point, you register your components globally.
import Vue from "vue";
import Some from "./some.vue"
const Components = {Some};
Object.keys(Components).forEach(name=>{
Vue.component(name,Components[name])
})
export default Components;
Next, you need to define a build step for building your library in your package.json, which links to the entry point of your component:
"scripts": {
...
"build-bundle" : "vue-cli-service build --target lib --name some ./resources/assets/js/components/index.js",
...
},
Next, call this build step, e.g. by invoking 'yarn build-bundle', or the npm equivalent.
Finally, you can add the compiled component to your webpage. Note, that you don't need to explicitly include your component, since you registered it globally before. Also note that you need to add the type="module" attribute to the script tage, because otherwise you cannot use the import statement. Finally, the outpath of the compiled libraries is the one that is used in your vue.config.js.
<div id='lol'>
<some-component></some-component>
</div>
<script type="module">
import "/<path>/<to>/<compiled>/<library>/some.umd.min.js";
const app = new Vue({
el: '#lol',
})
</script>

Resources