Laravel Jetstream Vue mixin route - laravel

In a new Laravel project created by the installer with the Jetstream option resources/js/app.js has a line that reads:
Vue.mixin({ methods: { route } });
PHPStorm reports that route is an unresolved variable or type. This happens, PHPStorm can be wrong. In a newly created application this does not cause an error.
However, when I upgraded an existing project to Laravel 8.10.0 and installed Jetstream via composer this does cause and issue. When running this npm run dev does not error, but the browser will report app.js:44258 Uncaught ReferenceError: route is not defined.
I can find no difference in app.js or bootstrap.js that would cause this. Where does this get imported or included so that I can check if it was done correctly in my upgrade?

The newly created app and the update both create a Blade template that includes the #routes directive. As I was comparing existing files I did not notice this difference.
This can be corrected by including the #routes directive in your blade template prior to the main scripts being loaded, as documented in the installation guide for ziggy.

With the suggestion of ToothlessRebel, this is how I solved my error :
Step 1 command line :
composer require tightenco/ziggy
npm install ziggy-js
php artisan ziggy:generate "resources/js/ziggy.js"
step 2 : modify webpack.mix.js :
mix.js('resources/js/app.js', 'public/js')
...
.webpackConfig(require('./webpack.config'));
And in ./webpack.config :
const path = require('path');
module.exports = {
resolve: {
alias: {
'#': path.resolve('resources/js'),
ziggy: path.resolve('vendor/tightenco/ziggy/src/js/route.js'),
},
},
};
Step 3 : app.js :
import route from 'ziggy';
import {
Ziggy
} from './ziggy';
...
Vue.mixin({
methods: {
route: (name, params, absolute) => route(name, params, absolute, Ziggy),
},
});
...
new Vue({
el: "#app",
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
},
}),
});
and finally a command : npm run dev
So, my dashboard and all mixin/ziggy routes are working...
Not anymore my vue-router routes ... I guess I have a conflit I have to resolve, but it's an other problem

Related

Vue components in Inertia with Laravel seems to load twice

With a newly created Laravel with Inertia and Vue project, I have an error that it runs code inside my vue components twice.
For a simple test demo, I have a Test.vue, with this code
<template>
<div>
TEST
</div>
</template>
<script>
export default {
name: "Test",
mounted() {
console.log('test')
}
}
</script>
<style scoped>
</style>
Route in web.php:
Route::get('/test', array(App\Http\Controllers\DashboardController::class, 'test'));
In controller:
public function test(): Response
{
return Inertia::render('Test');
}
When I go to the route /test, it echoes out 'test' twice on mounted in my console. In more advanced components which calls APIs and such, also calls them twice.
I suspect maybe my project is set up wrongly, in app.blade.php or app.js but cannot figure it out.
I followed the guides on https://inertiajs.com/server-side-setup and https://inertiajs.com/client-side-setup to set this up.
My source code is here: https://github.com/ekstremedia/laravel-inertia
Edit: It seems to only echo out twice in the first component I load. If I in that component link to another component, and go there, it doesn't load that twice.
I found that this is solved by modifying your app.js file in your resources directory thus:
import Vue from 'vue'
import { App as InertiaApp, plugin as InertiaPlugin } from '#inertiajs/inertia-vue'
Vue.use(InertiaPlugin)
new Vue({
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
},
}),
}).$mount(app);
Your problem seems to have been in how you initialized your inertia app.

Keep getting 'TypeError: Cannot call a class as a function' using Ziggy for Vue in Laravel

I have searched and searched and can't seem to find a solution to my problem.
I have taken the following steps:
\\Webpack.mix.js
const mix = require('laravel-mix');
const path = require('path');
mix.webpackConfig({
resolve: {
alias: {
ziggy: path.resolve('vendor/tightenco/ziggy/src/js/route.js'),
},
},
});
mix.js('resources/js/app.js', 'public/js').vue()
.postCss('resources/css/app.css', 'public/css', [
//
]);
mix.browserSync('127.0.0.1:8008');
And then in my app.js I have
\\app.js
require('./bootstrap');
import Vue from 'vue'
// Ziggy start here
import route from 'ziggy';
import { Ziggy } from './ziggy';
Vue.mixin({
methods: {
route: (name, params, absolute, config = Ziggy) => route(name, params, absolute, config),
},
});
// ziggy end here
import VendorLoginForm from './vue/components/vendors/auth/VendorLoginForm'
import VendorRegisterForm from './vue/components/vendors/auth/VendorRegisterForm'
import EditVendorProfile from './vue/components/vendors/profile/EditVendorProfile'
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate/dist/vee-validate.full.esm';
extend("password", {
message: "{_field_} must be at least 10 characters long, contain one uppercase, one lowercase, and one number.",
validate: value => {
const strong_password = new RegExp(
"^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{10,})"
); // regex to check our strong password
return strong_password.test(value); //Test the regex. Test function returns a true or false value.
}
});
import './scripts/validators'
Vue.component('ValidationProvider', ValidationProvider);
Vue.component('ValidationObserver', ValidationObserver);
Vue.component('extend', extend);
const app = new Vue({
el: '#vue-app',
components: { VendorLoginForm, VendorRegisterForm, EditVendorProfile }
});
I have ran the php artisan command to generate the ziggy.js and it seems to be working fine when I Ctrl+click it.
However when I got into my component to try to use route as below
mounted() {
console.log(this.route('home.page'))
},
I get the error:
app.js:51783 TypeError: Cannot call a class as a function
at _classCallCheck (app.js:3612)
at Route (app.js:3630)
at VueComponent.route (app.js:3345)
at VueComponent.mounted (app.cbfbd1ac1b8410f1ce58.hot-update.js:172)
at invokeWithErrorHandling (app.js:51749)
at callHook (app.js:54109)
at Object.insert (app.js:53032)
at invokeInsertHook (app.js:56234)
at VueComponent.patch [as __patch__] (app.js:56453)
at VueComponent.Vue._update (app.js:53838)
this was a nightmare when I was working with Ziggy at first time but I resolved my issue by
after creating ziggy.js in resources folder php artisan ziggy:generate
edit my webpack.mix.js file
const mix = require('laravel-mix');
const path = require('path');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/js/app.js', 'public/js')
.vue()
.sass('resources/sass/app.scss', 'public/css');
mix.webpackConfig({
resolve: {
alias: {
ziggy: path.resolve('vendor/tightenco/ziggy/dist'),//Note we point to dist folder
},
},
});
then in App.js
import route from 'ziggy';
import {
Ziggy
} from './ziggy';
Vue.mixin({
methods: {
route: (name, params, absolute) => route(name, params, absolute, Ziggy)
}
});
then you can use route in your components
console.log(route("home"));

Laravel 8 (Inertia js) - Getting Vue error 'app.js:30559 [Vue warn]: Error in created hook: "Error: Cannot find module...'

I have setup a Laravel 8 installation that uses Jetstream (inertia js stack). All Jetstream provided views are working correctly.
The issue is when I create a new Route that renders a new Vue template, I get this error in my console:
app.js:30559 [Vue warn]: Error in created hook: "Error: Cannot find module './Test'"
My Route created in web.php
Route::get('/test', function() {
return Inertia\Inertia::render('Test');
});
The 'Test.vue' file is in the 'resources/js/Pages' directory.
<template>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Testing
</h2>
</template>
app.js
require('./bootstrap');
import Vue from 'vue';
import { InertiaApp } from '#inertiajs/inertia-vue';
import { InertiaForm } from 'laravel-jetstream';
import PortalVue from 'portal-vue';
Vue.use(InertiaApp);
Vue.use(InertiaForm);
Vue.use(PortalVue);
const app = document.getElementById('app');
new Vue({
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
},
}),
}).$mount(app);
Any idea why the Test.vue template is not being found?
Maybe somebody else is getting here like I did - I had to open developer console in Chrome and make sure that in the Network tab, I had disable cache checked.
And on top, had to go into my server and do php artisan optimize to clear cached views.
Just needed to run 'npm run dev'
You should run this command: npm run watch
It will tracks all your changes and update the application.
Check if you have npm run watch or imho better npx mix watch. Try to php artisan optimize and of course, "hard reload" your browser - for Chrome it is Control+Shift+Delete on Windows and Command+Shift+Delete on MacOS
You need to run npm watch for the vue pages to render:
Route::middleware(['auth:sanctum', 'verified'])
->get('/chat', function () {
return Inertia::render('Chat/container');
})
->name('chat');
The error for me was in the way i created the module directory, it contained additional invisible characters different from its intended name so i had to recreate the directory and that solved it.
Ps : Anyone trying this can just refactor if possible

how to run vue app in the same domain with laravel sanctum for SPA

I need help in running my Vue spa in the same domain as my laravel app , when running "npm run serve" in terminal I think it's working but when I go to the browser it's refusing connection. I haven't done the backend which I will use sanctum for handling API. Has anybody here have the same project working on like me? love to make conversations to solve this.
Thanks in advance
here is the vue.config.js file
const path = require('path')
const webpack = require('webpack')
const createThemeColorReplacerPlugin = require('./config/plugin.config')
function resolve (dir) {
return path.join(__dirname, dir)
}
/**
* check production or preview(pro.loacg.com only)
* #returns {boolean}
*/
function isProd () {
return process.env.NODE_ENV === 'production'
}
const assetsCDN = {
css: [],
// https://unpkg.com/browse/vue#2.6.10/
js: [
'//cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.min.js',
'//cdn.jsdelivr.net/npm/vue-router#3.1.3/dist/vue-router.min.js',
'//cdn.jsdelivr.net/npm/vuex#3.1.1/dist/vuex.min.js',
'//cdn.jsdelivr.net/npm/axios#0.19.0/dist/axios.min.js'
]
}
// webpack build externals
const prodExternals = {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios'
}
// vue.config.js
const vueConfig = {
configureWebpack: {
// webpack plugins
plugins: [
// Ignore all locale files of moment.js
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
],
// if prod is on, add externals
externals: isProd() ? prodExternals : {}
},
chainWebpack: (config) => {
config.resolve.alias
.set('#$', resolve('src'))
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule
.oneOf('inline')
.resourceQuery(/inline/)
.use('vue-svg-icon-loader')
.loader('vue-svg-icon-loader')
.end()
.end()
.oneOf('external')
.use('file-loader')
.loader('file-loader')
.options({
name: 'assets/[name].[hash:8].[ext]'
})
// if prod is on
// assets require on cdn
if (isProd()) {
config.plugin('html').tap(args => {
args[0].cdn = assetsCDN
return args
})
}
},
css: {
loaderOptions: {
less: {
modifyVars: {
// less vars,customize ant design theme
'primary-color': '#00B4E4',
// 'link-color': '#F5222D',
'border-radius-base': '4px'
},
javascriptEnabled: true
}
}
},
}
if (process.env.VUE_APP_PREVIEW === 'true') {
vueConfig.configureWebpack.plugins.push(createThemeColorReplacerPlugin())
}
module.exports = vueConfig
module.exports = {
devServer: {
host: 'app.paymate-ui.test'
}
}
If I understand you correctly, you want to use Laravel and Vue.js together in the same application folder?
Should be pretty easy then.
First off, build your application with Vue scaffolding for the frontend.
Then, make a route that redirects everything to a single controller method that returns a spa view. (Or use a closure)
In this view, include your app.js as an asset and include the main Vue component (something like <app></app>).
Then build your Vue app. All requests will now be forwarded to the spa view, which includes your app.js, which should bootstrap Vue.

Laravel and vue: require is not defined

In Laravel version 6 the follwing error happens with vue in the console:
app.js:24703 Uncaught ReferenceError: require is not defined
at app.js:24703
the error points to:
require('./bootstrap');
Webpack.mix.js:
mix.scripts([
'resources/js/jquery-3.4.1.js',
'resources/js/bootstrap.min.js',
'resources/js/toastr.js',
'resources/js/vue.js',
'resources/js/axios.js',
'resources/js/app.js'
], 'public/js/app.js')
.styles([
'resources/css/bootstrap.min.css',
'resources/css/toastr.css'
], 'public/css/app.css');
It works fine VUEJS for me but it doesn’t allow me to add components
Also another thing that I notice is that this error disables me vue devtools.
The code is newly installed, both the Laravel and Vue project and if I create a new project I get the same error.
require('./bootstrap');
window.Vue = require('vue');
Vue.component('message', require('./components/message.vue').default);
const app = new Vue({
el: '#app',
data:{
message: ''
},
methods:{
send(){
if(this.message.length !=0){
console.log(this.message);
}
}
}
});
What am I doing wrong?
It sounds like, somehow, the file is given to the browser hasn't been compiled.
You need to change the configuration Webpack.mix.js
You can try change mix.scripts([]) on mix.js([]) and add .vue().
It helped me.
mix.js([
'resources/js/jquery-3.4.1.js',
'resources/js/bootstrap.min.js',
'resources/js/toastr.js',
'resources/js/vue.js',
'resources/js/axios.js',
'resources/js/app.js'
], 'public/js/app.js') .vue();

Resources