On refresh vuejs template is not working and I get just json Data, Vuejs and Laravel - laravel

I have a route where when I refresh the page I get only the JSON info for that page. (only on refresh F5). The rest of the routes are ok. I am not sure what I am doing wrong.
web.php
Route::get('/persons', 'MyController#index');
Route::post('/record/{personId?}', 'MyController#create'); // this is the one that don't work on refresh
Route::get('/record/{id}', 'MyController#getRecord');
Route::delete('/record/{id}', 'MyController#destroy');
Route::get('/lookups', 'LkpController#index');
Route::post('/validate', 'MyController#getValidation');
//Routes for VueJs
Route::get('/{any}', function () {
return view('welcome');
})->where('any','^(?!api).*$')->name('home');
router.js
const routes = [
{
path: "/",
name: "Home",
component: Home,
meta: { requiresAuth: true }
},
{
path: "/record",
name: "Record",
component: Record,
meta: { requiresAuth: true }
},
{
path: "/record/:id",
name: "View Record",
component: require ('./components/AddPerson').default,
meta: { requiresAuth: true }
}
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes
});
export default router;

The problem is that you are putting all your routes in web.php, and you have the same routes for your Vue SPA as your Laravel application.
You should put your API routes in your web/api.php file that way they will be automatically prefixed with the 'api' route.
The route that is returning JSON data is not the one you pointed out, it is the next one:
Route::get('/record/{id}', 'MyController#getRecord'); // this is the one that don't work on refresh
This is because your Vue router is pointing to the exact same route:
{
path: "/record/:id",
name: "View Record",
component: require ('./components/AddPerson').default,
meta: { requiresAuth: true }
}
Both routes point to yourwebsite.com/record/{id}, but on refresh you make a brand new request to your Laravel application, that means your not in your Vue application anymore and your browser will load whatever Laravel will tell them first, in this case it will be the first route in the routes/web.php file:
Route::get('/record/{id}', 'MyController#getRecord');
Edit: This is how you should do it if you cannot use API routes due to authentication:
You must make sure that your don't have duplicate routes between your Vue router and your Laravel routes, you can just prefix them with something that makes sense to you.
Route::prefix('prefix')->group(function () {
Route::get('/persons', 'MyController#index');
Route::post('/record/{personId?}', 'MyController#create');
Route::get('/record/{id}', 'MyController#getRecord');
Route::delete('/record/{id}', 'MyController#destroy');
Route::get('/lookups', 'LkpController#index');
Route::post('/validate', 'MyController#getValidation');
});
//Routes for VueJs
Route::get('/{any}', function () {
return view('welcome');
})->where('any','^(?!api).*$')->name('home');
In this example, the route you are having trouble with will now be prefixed with 'prefix' yourwebsite.com/prefix/record/{id}, you can change it to whatever you need it to be.

Related

Laravel middleware on a VueJS route

I have a VueJS route in my SPA application. I would like to apply a Laravel Middleware to a route (the auth middleware, in this case).
Actually, I have try this:
app.js
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: require('./views/Home').default,
},
{
path: '/hello',
name: 'hello',
component: require('./views/Hello').default,
},
],
});
routes/web.php
Route::get('/hello', 'HomeController#home')->middleware('auth');
Route::get('/{any}', 'FrontendController#index')->where('any', '.*');
In this code, I have try to link the auth middleware to the route /hello, but it don't work. What is the best way to do that ?
Thanks.
I have not worked with Laravel for about 6 years, but with Vue. I believe that this is because you never get into your Laravel route, since the Vue app is assembled, and it is therefore fully available in the browser.
It would be different if you loaded the component in the Vue router via lazy load.
component: () => import(/* webpackChunkName: "hello" */ './views/helo.vue')
I don't know exactly how that works with Laravel. I use the Vue CLI tool. Hope this could help you a little.

Laravel Routes with Vue Router (SPA) Not Working as normal

I am trying to create a Laravel Vue SPA application. And it seems that I cannot get the route all to function properly. Everytime I use the get('{any}') all my axios get methods call returns the index.blade.php. But if I define all routes in routes.js with more or less the same signature in my web.php (Laravel) my axios routes in getting the data works fine.
web.php
// This work but every time I do an Axios call it returns my index.blade.php
Route::get('{any}', 'SiteController')->where('any', '.*');
// This works if I define all routes, with axios fetching data normally and
// displaying the data in Vue normally
Route::get('/', 'SiteController');
Route::get('/blog', 'SiteController');
Route::get('/post/{postId?}', 'SiteController');
routes.js
const routes = [
{ path: '*', component: Home },
{
path: '/',
component: Home,
children: [
{
name: 'blog',
path: '/blog',
component: PageBlogLists,
},
{
name: 'post',
path: '/post/:page_id',
component: PageBlog,
},
],
},
];
export default new VueRouter({
base: '/',
fallback: true,
mode: 'history',
routes: routes,
});
So I finally got it working I've changed my routes to
Route::get('/{any}', 'SiteController')->where('any', '^(?!api).*$');
and move all my API requests to the api.php file
Route::resource('/posts', 'WordpressController');
router.js and axios works fine now :)
So first the root view, I do not know how does yours look like but it should be something like this
Route::get('{path}', function () {
return view('index');
})->where('path', '(.*)');
Second, you are building SPA, you should not be using web.php, you should use api.php
if you have to and really want to use web.php, you can move the any down to the bottom, and prefix all the other routes with something else.
I do not have a clear picture of the other codes you have in your hands.
But for laravel vue router, this reference helps me a lot
https://medium.com/#weehong/laravel-5-7-vue-vue-router-spa-5e07fd591981
You could give it a try. Hope this helps.

Skip login screen while opening a vue route link

I am using laravel and vue js in my app. All the vue routes ask for a login when opened as i am using laravel auth. I want to create some routes that should be accessable without a user to be logged in. In other words I want some route that can be accessed by guest user as well. But at the moment all routes require user to be authenticated. These are my routes
const routes = [
{ path: '/dashboard_admin', component: require('./components/dashboard.vue').default},
{ path: '/ongoing_events_admin', component: require('./components/events.vue').default } ,
{ path: '/courses_admin', component: require('./components/courses.vue').default},
{ path: '/front_images_admin', component: require('./components/front_images.vue').default},
{ path: '/news_admin', component: require('./components/news.vue').default},
{ path: '/main', component: require('./components/main_view/index_view_general.vue') ,
name: 'index',
props: true ,
beforeEnter:DontrequireLogin
},
//general vue
// { path: '/', component: require('./components/main_view/index_view_general.vue').default},
]
const router = new VueRouter({
mode: 'history',
routes // short for `routes: routes`
})
const app = new Vue({
el: '#app',
router
});
These are my routes. I want some of these routes that can be accessed by guest user as well but at the moment all routes require user to be logged in.
So you need to do this meta's, for more about this you can read from its official documentation Route Meta
Let me explain litle bit what meta's do .
in meta you define a bolean object which indicate , this route is for authenticated or users or for guest user. let see below example.
i have authenticated route, only for authenticated users.
{path: '/account-setting',component:accountSetting,meta:{auth:true}},
so i pass auth object in meta and decide in route.beforeach what to do with this route.
so same a normal route
{path: '/about',component:about}
in this i give no meta, which means its for all user.
read the documentation to know how to use it.

Laravel + Vue router - Best practice for slugs

I have a laravel + vue app. I've created a vue spa application for a particular page called shop. In this shop, I have 3 sub pages which is about, products and contact.
routes.php
Route::get('/shop/{slug}/{vue_capture?}', 'ShopController#show')->where('vue_capture', '[\/\w\.-]*');
vue-router.js
export const routes = [
{ path: '/', component: Home, name: 'home',
children: [
{
path: '/',
name: 'about',
component: About
},
{
path: '/products',
name: 'products',
component: Product
},
{
path: '/contact',
name: 'contact',
component: Contact
}
]
},
];
So for example I go to domain.com/shop/joe-shop, what is the best practice to extract the slug and use it in my vue application so I can make http requests with slug parameter to server? Thank you
note: I'm also using vuex state management in my app
var slug = window.location.pathname.replace(/^\/shop\/([^\/]+)(?:\/.*)?/i,'$1');
Note:
With your current set-up, you would need to set the base property in your vue-router config to behave properly.
new Router({
base: window.location.pathname.replace(/^(\/shop\/[^\/]+).*/i,'$1'),
mode: 'history',
routes: ...
})

Views Not Creating in Custom Routes in Laravel + Vue.Js

I am Using Laravel 5.5 and Vue.js 2.0
When i open example.com and click on Display Items then this url triggered example.com/items
and here are results
and When i open directly this url example.com/items it shows me only json response that i am getting from Laravel without creating any view in html (Vue.js).
See Below:
How Can I Get Exact Results in Browser by Visiting Direct Urls like example.com/items without visiting example.com first.
Updated
Here is My Vue routes.js File
import Example from './components/ExampleComponent.vue'
import CreateItem from './components/CreateItem.vue'
import DisplayItem from './components/DisplayItem.vue'
import EditItem from './components/EditItem.vue'
export const routes = [
{ name: 'Example', path: '/', component: Example },
{ name: 'CreateItem', path: '/items/create', component: CreateItem },
{ name: 'DisplayItem', path: '/items', component: DisplayItem },
{ name: 'EditItem', path: '/items/:id/edit', component: EditItem }
];
Getting Response From Laravel Like This
$items = Items::all();
// dd($items);
return response()->json($items);
DisplayItems.vue File Vue.js Code
<script>
export default {
data(){
return{ items: [] }
},
created: function()
{
this.fetchItems();
},
methods: {
fetchItems()
{
this.axios.get('/items').
then(response => {
this.items = response.data;
});
},
deleteItem(id)
{
let uri = '/items/'+id;
this.items.splice(id, 1);
this.axios.delete(uri);
}
}
}
</script>
Laravel is returning a JsonResponse from the route /items, hence why you see JSON in the browser. Vue binds the JSON to dom elements.
You would need to modify the route to /items so that it returns JSON if $request->wantsJson() and a regular Response if non ajax.
[BEHAVIOUR]
laravel have it's own server with routes.
When you trying to refresh custom Vue.js route, it shows overrides Vue.js routes with laravel route and shows you only JSON response.
[SOLUTION]
You should create Vue.js application and Use laravel-echo or laravel broadcasting and use laravel api.
Now make each request from Vue to direct API and Get Response.

Resources