vue-moment issue in laravel-inertia - laravel

I tried importing vue-moment and initializing it by using .use(VueMoment) as shown below. But after i do that the whole app shows error. Anyone facing the same problem?
require('./bootstrap');
// Import modules...
import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
import VueMoment from 'vue-moment' ////////imported vue-moment
const el = document.getElementById('app');
createApp({
render: () =>
h(InertiaApp, {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
}),
})
.mixin({
methods: {
route,
validationError(field){
if(this.$page.props.errors && this.$page.props.errors[field]){
return this.$page.props.errors[field];
}
else{
return null;
}
}
} })
.use(InertiaPlugin)
.use(VueMoment) /////use vue-moment
.mount(el);
InertiaProgress.init({ color: '#4B5563' });
This is the error i am getting

first install moment by
npm install moment
<template>
{{today}}
</template>
<script>
import moment from 'moment'
export default {
name:'Home',
data(){
return{
today:moment().startOf('day').toDate(), moment().endOf('day').toDate()
}
}
</script>

there is a working example of how to import 'vue-moment' from my Laravel + inertia project
const vm = new Vue({
metaInfo: {
titleTemplate: title => (title ? `${title} - Ping CRM` : 'Ping CRM'),
},
store,
render: h =>
h(App, {
props: {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: name => import(`#/Pages/${name}`).then(module => module.default),
},
}),
}).$mount(el)
Vue.use(require('vue-moment'))

Might help someone who is using InertiaJs with Vue and want to declare globally.
In app.js
createInertiaApp({
id: 'app',
setup({ el, App, props}) {
let app = createApp({
render: () => {
return h(App, props);
},
});
//you can declare any other variable you want like this
app.config.globalProperties.$moment = moment;
app.use(
store,
.....
).mount(el);
},
});
Now in the vue file you can call moment by
this.$moment(this.time,'H:m').format('hh:mm a');

Related

How to add VueGoogleMaps configuration on app.js

Hello i need help to add VueGoogleMaps from #fawmi/vue-google-maps
i got confused on how to add that to may laravel inertia vue project.
this is my app.js configuration and still not working.
import "../css/app.css";
import { createApp, h } from "vue";
import { createInertiaApp } from "#inertiajs/inertia-vue3";
import { InertiaProgress } from "#inertiajs/progress";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
import { ZiggyVue } from "../../vendor/tightenco/ziggy/dist/vue.m";
import { createPinia } from "pinia";
import { VueGoogleMaps } from "#fawmi/vue-google-maps";
const appName =
window.document.getElementsByTagName("title")[0]?.innerText || "Laravel";
const pinia = createPinia();
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) =>
resolvePageComponent(
`./Pages/${name}.vue`,
import.meta.glob("./Pages/**/*.vue")
),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.use(pinia)
.use(ZiggyVue, Ziggy)
.use(VueGoogleMaps, {
load: {
key: "", // i have my API key on .env GOOGLE_MAPS_API_KEY
},
})
.mount(el);
},
});
InertiaProgress.init({ color: "#4B5563", showSpinner: true });
Code on how to fix my problem.

Default layout doesn't work in Laravel + Vite + Svelte

I started my first project with Laravel + Vite (I already used Inertia with Laravel + Webpack) and the problem I have is the default layout.
When using Webpack I could define the layout with the following code:
createInertiaApp({
resolve: name => {
const page = require(`../svelte/Pages/${name}.svelte`);
if (guestPages.indexOf(name) !== -1) {
page.layout = LayoutGuest
} else {
page.layout = Layout
}
return page
},
setup({ el, App, props }) {
new App({ target: el, props })
},
})
But now, with the new Vite way, I can't get it to work.
Here's the code I have:
async function resolve(name)
{
const page = resolvePageComponent(`../svelte/Pages/${name}.svelte`, import.meta.glob('../svelte/Pages/**/*.svelte'));
let component;
await page
.then(module => {
module.default.layout = Layout;
component = module;
});
return component;
I don't know if the problem is the dynamic import.
With the help of an Inertia server member on Discord (Robert Boes) and writing a few lines of code, I found the solution:
// import './bootstrap';
import { createInertiaApp } from '#inertiajs/inertia-svelte'
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
import "../less/app.less";
import Layout from "../svelte/Base/Layout.svelte";
async function resolve(name)
{
let component;
const pagesWithoutLayout = [
'Session/Index',
];
const page = resolvePageComponent(`../svelte/Pages/${name}.svelte`, import.meta.glob('../svelte/Pages/**/*.svelte'));
await page
.then(module => {
component = pagesWithoutLayout.includes(name) ?
module :
Object.assign({ layout: Layout }, module);
});
return component;
}
createInertiaApp({
resolve,
setup({ el, App, props }) {
new App({ target: el, props })
},
});
I made it work without Svelte with the following code snipped.
Hope it helps and maybe you can adapt it to your needs.
Im using it in a TypeScript environment, which is why I added "as any;".
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: async (name) => {
const page = resolvePageComponent(
`./Pages/${name}.vue`,
import.meta.glob("./Pages/**/*.vue")
) as any;
await page.then((module) => {
//if name starts with auth, then use login layout
if (name.startsWith("Auth/")) {
module.default.layout = module.default.layout || LoginLayout;
} else if (name.startsWith("Public/")) {
module.default.layout = module.default.layout;
} else {
module.default.layout = module.default.layout || AppLayout;
}
});
return page;
},
setup({ el, app, props, plugin }) {
createApp({ render: () => h(app, props) })
.use(plugin)
.use(createPinia())
.mount(el);
},
});

How to load Vue directive with Inertia JS in Laravel (Jetstream)

My original app.js looked like this. I noticed I can't add Vue directives because the createApp has no variable.
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.mixin({ methods: { route } })
.mount(el);
},
});
After some research this lead me to this where the directive still doesn't work. Any tips?
const clickOutside = {
beforeMount: (el, binding) => {
el.clickOutsideEvent = event => {
// here I check that click was outside the el and his children
if (!(el == event.target || el.contains(event.target))) {
// and if it did, call method provided in attribute value
binding.value();
}
};
document.addEventListener("click", el.clickOutsideEvent);
},
unmounted: el => {
document.removeEventListener("click", el.clickOutsideEvent);
},
};
const el = document.getElementById('app');
const app = createApp({
render: () =>
h(InertiaApp, {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
}),
});
app.directive('click-outside', clickOutside);
app.mixin({ methods: { route } })
.mixin({ directives: { clickOutside } })
.use(InertiaPlugin);
app.mount(el);

Using vuex on Laravel 8 with Inertia Stack

I'm learning how to use Vuex, and I'm trying to use it on a Laravel 8 with Inertia Stack, i'm using vue 3.
Store/index.js
import { Store } from 'vuex'
export const store = new Store({
state () {
return {
count:0
}
},
mutations:{
INCREMENT(state){
state.count++
},
DECREMENT(state){
state.count--
}
}
})
And here's my app.js
require('./bootstrap');
import { createApp, h } from 'vue';
import { createInertiaApp } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
import Vuex from 'vuex';
import { store } from './Store'
const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props),store })
.use(plugin)
.use(Vuex)
.mixin({ methods: {
route,
}
})
.mount(el);
},
});
InertiaProgress.init({ color: '#4B5563' });
But I always end up with a console error:
app.js:106250 Uncaught Error: [vuex] must call Vue.use(Vuex) before creating a store instance.
I've also tried:
.use(store)
But it doesn't seem to work. I'll appreciate if someone can point me what i'm missing or what I'm doing wrong
I had this problem too with vuex 3.x.x
I did this and it worked:
npm uninstall --save vuex
Then i reinstalled it :
npm install --save vuex#next (vuex 4.x.x)
In app.js I used .use(store).
And I don't know if it change anything but in store/index.js I exported as export default new Store({...})
Store/index.js
import { createApp } from 'vue';
import { createStore } from 'vuex';
const store = createStore({
state: {
count:0
},
mutations:{
INCREMENT(state){
state.count++
},
DECREMENT(state){
state.count--
}
}
})
export default store
And here's my app.js
require('./bootstrap');
import { createApp, h } from 'vue';
import { createInertiaApp } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
import store from '#/store/index';
const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props),store })
.use(plugin)
.use(store)
.mixin({ methods: {
route,
}
})
.mount(el);
},
});
InertiaProgress.init({ color: '#4B5563' });

Laravel + Vue.js - how to have a global variable?

I have a project using Laravel and Vue.js. I guess it wasn't the best idea not to separate them, but we learn from our mistakes ;)
Here is how it works:
I have been struggling trying to put global variables, such as "current user". Now, I am calling /currentuser through axios each time I need it, or I put it in props, but it drives my crazy... How can I make it global?
I am wondering if Vuex could work in my project, as everything is called from Laravel, the routes as well...
I have tried several things in app.js (here are 2 of them, mixed):
var curruser=null;
axios.get('/currmember').then(
response => {
curruser=response.data;
}
);
Vue.mixin({
methods: {
},
data: function() {
return {
myvaiable: '', //this doesn't work eather
get currentUser() {
if(curruser==null){
axios.get('/currmember').then(
response => {
curruser=response.data;
return curruser;
}
);
}
return curruser;
}
}
}
});}
in TestComponent.vue
<template>
<div>
{{currentUser}}
{{myvariable}} <!-- none of them display anything -->
</div>
</template>
Here is how things are working (simplify them very much):
app.js
import Vue from 'vue';
window.Vue = require('vue');
var App = Vue.component('app', require('./App.vue').default, {
name: 'app'
});
var shol = Vue.component('test', require('./components/TestComponent.vue').default);
let lang=localStorage.Lang!=null?localStorage.Lang:'fr';// = document.documentElement.lang.substr(0, 2);
init();
function init(){
const app = new Vue({
el: '#app',
i18n,
components:{test
}
});
var curruser=null;
axios.get('/currmember').then(
response => {
curruser=response.data;
}
);
Vue.mixin({
methods: {
},
data: function() {
return {
currentUser: 'blabla',
get currentUser2() {
if(curruser==null){
axios.get('/currmember').then(
response => {
curruser=response.data;
console.log(curruser);
return curruser;
}
);
}
return curruser;
}
}
}
});}
test.blade.php
#extends('template')
#section('pageTitle', 'test' )
#section('contenu')
<div >
<test></test>
</div>
#endsection
web.php
Route::get('/test', function () {
return view('test');
});
You may use vuex to access current authenticated user:
On app.js:
import Vue from 'vue';
import store from './store';
const app = new Vue({
el: '#app',
store,
i18n,
components:{ test },
created() {
store.dispatch('getUser');
}
});
The store.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {},
},
getters: {
user: state => state.user,
},
mutations: {
setUser(state, user) {
state.user = user;
},
},
actions: {
getUser({ commit }) {
return new Promise((resolve, reject) => {
axios.get('/currmember')
.then(result => {
commit('setUser', result.data);
resolve();
})
.catch(error => {
reject(error.response && error.response.data.message || 'Error.');
});
});
},
}
})
The test component:
<template>
<div>
{{ currentUser }}
</div>
</template>
<script>
export default {
computed: {
currentUser() {
return this.$store.state.user;
}
}
};
</script>

Resources