Laravel 9 Vue 3 Inertia Project - laravel

I'm building an SPA with Laravel and Vue.js with vite, and I have another project with Laravel Breeze and Inertia js for the CMS. How can I merge these 2 projects into one ? So I can have an SPA project with CMS on it like an admin page that u can set through the routes.
Is it possible ?
This is the app.js in my CMS project
import '../css/app.css';
import { createApp, h } from 'vue';
import { createInertiaApp } from '#inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';
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(ZiggyVue, Ziggy)
.mount(el);
},
progress: {
color: '#4B5563',
},
});
This is the app.js in my SPA project
import '../css/navbar.css';
import '../css/home.css';
import '../css/kenapa.css';
import '../css/ceritakami.css';
import '../css/karir.css';
import '../css/lowongan.css';
import '../css/media.css';
import '../css/gabung.css';
import '../css/mitra.css';
import '../css/download.css';
import '../css/footer.css';
import { createApp } from 'vue';
import App from './layouts/app.vue';
createApp(App).mount('#app');
I tried to copy the pages into the CMS and vice versa, but It just keep giving me errors.
I'm a beginner and I just don't get it using inertia, because in my SPA project, I'm using App.vue as a layout to call other pages like this :
<NavbarVue/>
<Home/>
<Kenapa/>
<Cerita/>
<Karir/>
<Lowongan/>
<Media/>
<Gabung/>
<Mitra/>
<Download/>
<Footer/>
</template>
<script setup lang="ts">
import NavbarVue from '../components/Navbar.vue';
import Home from '../pages/Home.vue';
import Media from '../pages/Media.vue';
import Kenapa from '../pages/Kenapa.vue';
import Cerita from '../pages/Cerita.vue';
import Lowongan from '../pages/Lowongan.vue';
import Karir from '../pages/Karir.vue';
import Gabung from '../pages/Gabung.vue';
import Mitra from '../pages/Mitra.vue';
import Download from '../pages/Download.vue';
import Footer from '../components/Footer.vue';
</script>
But in Inertia I can't do that, Can someone enlighten me ?

Migration
Make a new Laravel 9 project and follow the instructions for installing Breeze w/ Inertia nad Vue.
https://laravel.com/docs/9.x/starter-kits#breeze-and-inertia
You will then move the *.vue files over to the new project and parse them appropriately.
For instance, you may get data via Axios calls in your Spa. With Inertia, you pass data directly from the controllers.
Furthermore, you will have to import your controllers and all related PHP files into the new project and parse them to align with the Inertia design structure.
Testing
If you haven't already, I highly suggest you get into testing with PHPUnit. Properly tested code can make migrating files from one repository to another less nerve-wracking.
https://laravel.com/docs/9.x/testing
Conclusion
Overall, this would be a massive project that could possibly take months. But if you intend to combine two completely different projects into one, that complexity will require it, especially if neither is tested.

Related

How to import LaravelVuePagination library in Vue3 Script Setup

When I try to import the library using script setup it doesn't work.
<script setup>
import LaravelVuePagination from "laravel-vue-pagination";
.....
<script>
Documentation has only included importing by components
import LaravelVuePagination from 'laravel-vue-pagination';
export default {
components: {
'Pagination': LaravelVuePagination
}
}
Well I can't use the following code in template with script setup
<Pagination
style="page"
:data="supplier.data"
#pagination-change-page="pageData"
/>
</div>
the above code should work if you have installed it.
npm install laravel-vue-pagination
// or
yarn add laravel-vue-pagination
if it's already installed and it's not importing then you can try importing from app.js or main.js where you have initialized your Vue object.
require('./bootstrap');
require('alpinejs');
import { createApp } from 'vue'
import App from '#/App.vue'
import router from "#/routes"
import axios from 'axios'
import Vuex from 'vuex'
import store from './store'
import LaravelVuePagination from 'laravel-vue-pagination';
const app = createApp(App)
app.config.globalProperties.$axios = axios;
app.component('Pagination',LaravelVuePagination);
app.use(router);
app.use(store);
app.use(Vuex);
app.mount('#app')
Visit https://www.npmjs.com/package/laravel-vue-pagination

how can I sole resolve error for vue, that does not occurs locally?

In my app I use Login.vue and Logout.vue components, located in
/resources/js/components/auth
Locally the app runs fine on localhost.
Now I pushed to app to the remote repository, and the I get the following error after running:
npm run production
the error is:
ERROR Failed to compile with 1 errors 3:05:45 PM
error in ./resources/js/app.js
Module not found: Error: Can't resolve './components/auth/Login.vue' in '/var/www/ijsbrekerz/resources/js'
app.js looks like:
**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
import 'bootstrap';
import { createRouter, createWebHistory } from 'vue-router';
import routes from './routes.js';
import store from './store';
import vuex from 'vuex';
import { createApp } from 'vue';
import axios from 'axios';
import Master from'./components/layouts/Master.vue';
import ExampleComponent from'./components/ExampleComponent.vue';
import ManageCards from'./components/ManageCards.vue';
import Navibar from'./components/Navibar.vue';
import CreateSpeler from'./components/CreateSpeler.vue';
import CardsSpeler from'./components/CardsSpeler.vue';
import Home from'./components/Home.vue';
import ModalComponent from'./components/ModalComponent.vue';
import Game from'./components/Game.vue';
import GameAdmin from'./components/GameAdmin.vue';
import Login from'./components/auth/Login.vue';
import Logout from'./components/auth/Logout.vue';
import ImageUpload from'./components/ImageUpload.vue';
import Memory from'./components/Memory.vue';
// link naar uilteg opzetten routes..
const router = createRouter({
history: createWebHistory(),
routes: routes.routes,
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (!store.getters.loggedIn) {
next({
name: 'login',
})
}
} else if (to.matched.some(record => record.meta.requiresVisitor)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (store.getters.loggedIn) {
next({
name: 'gameadmin',
})
}
} else if (to.matched.some(record => record.meta.requiresVisitor)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (store.getters.loggedIn) {
next({
name: 'cards',
})
} else {
next()
}
} {
next() // make sure to always call next()!
}
})
const app = createApp({
components: {
ImageUpload,ExampleComponent,ManageCards,CardsSpeler,Memory,Home, Navibar, CreateSpeler, Game, ModalComponent, CardsSpeler, GameAdmin,Login,Logout// hier alle data en functies waar vue wat mee moet
}
});
app.use(router);
app.use(store);
app.use(vuex);
app.component('ModalComponent', ModalComponent);
app.component('CreateSpeler', CreateSpeler);
app.component('CardsSpeler', CardsSpeler);
app.component('ManageCards', ManageCards);
app.component('Navibar', Navibar);
app.component('Login', Login);
app.component('Logout', Logout);
app.component('Master', Master);
app.component('ImageUpload', ImageUpload);
app.component('Memory', Memory);
app.mount('#app');
///window.Vue = require('vue').default;
/**
* 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('example-component', require('./components/ExampleComponent.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 app = new Vue({
// el: '#app',
//});
The directory structure of components is:
> app/resources/js/components/
>auth
>Login.vue
>Logout.vue
>layouts
>Master.vue
>CreateSpeler.vue
>ManageCards.vue
>etc
Can anyone understand why this is no problem locally, but on the remote server it generates the error?
I have installed vue#next, laravel-mix#next
First of all, I don't see where is the app.js is located in your directory structure but I am assuming that it is inside the app/resources/js directory.
Now if you are having errors at the server only but not in the local, I suggest the below possible solutions.
You might be running the project locally on a windows machine. In windows, the path doesn't strictly check. For example, auth/Login.vue and auth/login.vue will be treated as the same but in the Linux system, they are treated differently. Hence, check if the Login.vue is not actually login.vue.
Try to run production mode in the local machine and check if you get the same error or not. If you get an error there too, you might have a spelling mistake somewhere or the directory structure is wrong.

React Hook "useState" cannot be called at the top level

I am a beginner in react. I'm trying to send values of my database from one file to another using react-hooks, and getting the following error can anyone help me with this?
Line 5:41: React Hook "useState" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks
Code:
import React, {useState, useEffect} from "react";
import Axios from "axios";
const [collegeList, setcollegeList]=useState([]);
useEffect(()=>{
Axios.get("http://localhost:3001/api/get").then((response)=>{
setcollegeList(response.data);
});
}, []);
CollegeList = collegeList;
export default CollegeList;
You must use react hooks in react components. There're two ways i can recommend to you to fix this.
first) Doing it in your component
import React, {useState, useEffect} from "react";
import Axios from "axios";
function CollegeListComponent() {
const [collegeList, setcollegeList]=useState([]);
useEffect(()=>{
Axios.get("http://localhost:3001/api/get").then((response)=>{
setcollegeList(response.data);
});
}, []);
return "YOUR VIEW ELEMENTS"
second) Use it as react hook
import React, {useState, useEffect} from "react";
import Axios from "axios";
// making a custom react hook like this
function useCollegeList() {
const [collegeList, setcollegeList]=useState([]);
useEffect(()=>{
Axios.get("http://localhost:3001/api/get").then((response)=>{
setcollegeList(response.data);
});
}, []);
return { collegeList }
and then you can import useCollegeList in your component to use it

Laravel VuetifySetup

I followed a tutorial on youtube for Vuetify setup with laravel. I managed to set up the project successfully, i.e. install all dependencies as specified in the tutorial. Although in the final step, NPM watch, I get the following error in the console;
Uncaught TypeError: _plugins_vuetify__WEBPACK_IMPORTED_MODULE_1__.default is not a constructor
vuetify.js code:
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
const opts = {}
export default new Vuetify(opts)
The problem is exactly lies where you exporting default Vuetify.
The best practice to this is to import Vuetify in the separate file in the plugins for example so I will keep this up with this practice.
So after running:
$ npm install vuetify --save
// OR
$ yarn add vuetify
to install Vuetify on existing applications through the Webpack or creating a new Vue.js project just like this:
$ vue add vuetify
You should follow the below instruction.
Vuetify v1.5.*
If you are using Vuetify v1.5.* follow the below instruction (otherwise, skip this to the next one)
First of all you don't have to export Vuetify in this version and you just have to import Vuetify and tell Vue to use it. So the plugins/vuetify.js should be like this (You can also directly do the following in your main.js or app.js):
// /plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
NOTE: You can also define some setting in the above file within the Vue.use and pass it as an object just like this:
Vue.use(Vuetify, {/*Your setting goes here*/})
And then import it like below in your main.js or app.js:
// main.js or app.js
import Vue from 'vue'
import 'vuetify/dist/vuetify.min.css' // You also need to import Vuetify CSS file and also ensure you are using css-loader
import './plugins/vuetify' // We have assuemed the above snippet is in the plugins directory and it lies next to main.js or app.js
...
new Vue({
el: "#app",
router,
store,
render: h => h(App),
})
Vuetify v2.*.*
After adding it through your Webpack you need to locate webpack.config.js and add the following setting into your Webpack to configure the loader:
// webpack.config.js
module.exports = {
rules: [
{
test: /\.s(c|a)ss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
// Requires sass-loader#^7.0.0
options: {
implementation: require('sass'),
fiber: require('fibers'),
indentedSyntax: true // optional
},
// Requires sass-loader#^8.0.0
options: {
implementation: require('sass'),
sassOptions: {
fiber: require('fibers'),
indentedSyntax: true // optional
},
},
},
],
},
],
}
After that just create a plugin directory and then vuetify.js file like and add the following into it:
// /plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
Vue.use(Vuetify)
const opts = {}
export default new Vuetify(opts)
Then navigate to your main entry (main.js or app.js) and import it like below:
// main.js or app.js
import Vue from 'vue'
import vuetify from '#/plugins/vuetify' // We have assumed the above snippet is in the plugins directory and it lies next to main.js or app.js
new Vue({
vuetify,
}).$mount('#app')
NOTE: This much more sound like an instruction but for more information you can visit the documentation here.

Using prerender-spa-plugin with Laravel Vue.js in the resources directory

I have installed the prerender-spa-plugin via npm in my Laravel app that has the Vue.js app in the resources directory. How do I call the prerender-spa-plugin
in it? I have seen quite a bit examples of a standalone app but nothing that will support it in the resources directory.
To use plugin in a component only: known as local registration
<script>
import 'plugin_name' from 'plugin_directory' //located at /node_modules
//to use it in component call it like shown below
export default{
...
}
</script>
Then use it according to its application
To use it in multiple components/views. Known as global registration
In app.js import component and register it
import Plugin from 'plugin_directory'
Vue.use(Plugin)
For example. to use axios, we import it and register it globally in app.js like this
import axios from 'axios'
Vue.use(axios)
//that's it
This is how we can register multiple plugins globally in Vue in app.js
require('./bootstrap');
import Vue from 'vue'
import axios from 'axios';
import VueAxios from 'vue-axios';
Vue.use(VueAxios,axios);
import VueRouter from 'vue-router';
Vue.use(VueRouter);
Vue.config.productionTip =false;
import VeeValidate from 'vee-validate';
Vue.use(VeeValidate);
import Notifications from 'vue-notification'
Vue.use(Notifications)
import VueHolder from 'vue-holderjs';
Vue.use(VueHolder)
import App from './layouts/App'
import router from './router'
Vue.component('example-component', require('./components/ExampleComponent.vue'));
Vue.component('autocomplete', require('./components/AutoComplete.vue'));
Vue.component('topnav', require('./components/Nav.vue'));
Vue.component('imageupload', require('./components/ImageUpload.vue'));
const app = new Vue({
el: '#app',
router,
template:'<App/>',
components:{ App }
});

Resources