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.
Related
I'm trying to create something simple with Laravel + Vue.js without having to use the database.
I have two inputs from a Vue Component, and I was wondering how I pass those two values back into a Controller.
Usually, you use Axios to complete CRUD functions, but I honestly just want to pass simple values to the backend, and then have the backend transfer an array into back to the Vue Component.
Any advice? All the decent tutorials online usually use a database to transfer data back and forth.
Have you heard of inertiajs?
inertiajs allows you to create fully client-side rendered, single-page apps, without much of the complexity that comes with modern SPAs. It does this by leveraging existing server-side frameworks.
I was able to send data back and forth using axios
Here is what I had for my Vue Component:
<template> ... </template>
<script>
export default {
data() {
return {
name: '',
days: ''
}
},
methods: {
getData() {
axios.get('/api/urihere', {
params: {
name: this.name,
days: this.days
}
}).then((response) => {
console.log(response.data)
}).catch((error) => {
console.log(error)
})
}
},
mounted() {
//
}
}
</script>
While I had you had a simple get for Routes
Route::get('/urihere', [UrihereController::class, 'someMethod']);
and inside the said-controller
public function someMethod(Request $request)
{
return [$request->name, $request->days];
}
I need help about Axios.
I develop a SPA webapp on Laravel 6 (with package SPARK) and VueJS (version 2).
On a Vue component, I want to retrieve datas from my bdd.
So, I use Axios to make a get request on an API uri.
But, when I call Axios request, data field in Response object is a HTML code.
This is my code :
routes/web.php
Route::get('/', function(){
return view('welcome');
});
Route::middleware('auth')->get('/{any?}', function (){
return view('documents');
})->where('any', '[\/\w\.-]*');
The "welcome" view is a blade page where redirect on "/login" if user is not authenticate.
Otherwise, it redirect on "/home".
The link "/home" is define on vue-router in app.js.
The other route is the unique way to display the webapp (it's a single page application).
The Vue instanciation is in "passeport" view.
resources/js/app.js
import 'es6-promise/auto'
require('spark-bootstrap');
require('./components/bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import VueAxios from 'vue-axios';
import axios from 'axios';
Vue.use(VueAxios, axios);
Vue.component('index', require('./components/pages/index').default);
import Dashboard from './components/pages/dashboard.vue';
...
const routes = [
{
name: 'dashboard',
path: '/home',
component: Dashboard,
},
{...}
]
const router = new VueRouter({
history: true,
mode: 'history',
routes: routes
});
var app = new Vue({
mixins: [require('spark')],
router,
});
router package is added in Vue instanciation.
it is in the same context than spark component (identify by the #spark-app element)
resources/views/documents.blade.php
#extends('spark::layouts.app')
#section('content')
<div id="app">
<index :user="user"></index>
</div>
#endsection
It is the view returned for any path.
In the spark::layout.app, there is only a div with id="spark-app" and the #yield('content').
resouces/js/components/pages/index.vue
<template>
<transition name="fade">
<Component :is="layout" :user="user">
<router-view :layout.sync="layout" :user="user"></router-view>
</Component>
</transition>
</template>
.
.
<script>
const default_layout = "default";
export default{
props: ['user'],
data(){
return{
layout: 'div',
}
},
}
</script>
It's just the vue component with the router-view configure with a layout.
resources/js/components/pages/dashboard.vue
<template>
...
</template>
<script>
import Default from './../layouts/Default.vue'
export default {
props: ['user'],
data: function () {
return {
documents: []
}
},
created() {
this.$emit('update:layout', Default);
},
mounted(){
// extract passeports's informations
this.axios.get('/api/documentslist').then(response => {
console.log(response);
this.documents= response.data.data;
});
}
}
</script>
Here, I call the documentslist API define in routes/api.php.
routes/api.php
Route::middleware('auth:api')->group(function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
Route::get('/documentslist', 'DocumentController#list');
});
app/http/Controllers/DocumentController.php
...
public function list(Request $request){
return DocumentCollection(Document::all());
}
...
When I go to "/home", I verified "documents" data in Vue (or in the javascript console log), and response.data = "\r\n\r\n\r\n (...) v-if=\"notification.creator\" :src=\"notification.creator.photo_url\" class=... (10024 total length)"
But, list method in DocumentController have to return a list of documents, and not a HTML code.
Furthermore, I use Passport Laravel to unified authentication by login and the API token.
And the Axios request work in the same project without SPA structure.
I hope I'm clear in the problem explanation, and that I forget any detail to understand.
Thanks.
You can simply return like this from your controller
return response()->json(Document::all());
I suspect the API link to redirect with the SPA route (in routes/web.php, any path return the "home" view).
I try to change route in routes/web.php.
instead of :
Route::middleware('auth')->get('/{any?}', function (){
return view('home');
})->where('any', '[\/\w\.-]*');
I put this :
Route::middleware('auth')->get('/home', function (){
return view('home');
});
Like this, this route doesn't take account of all path.
And...it works !
But...it isn't what I want :(
Indeed, without the route with '/{any?}' the SPA doesn't work.
I don't understand why this method works another project in Laravel (without Spark package), and doesn't work with this project.
I don't know about laravel but this problem arises when the route you are calling is not the correct one. Do some efforts and check what route the application in eventually calling also take a look at your proxy settings.
****I am NodeJs developer not 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.
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.
I have Laravel in api folder and Vue is in the root folder, and I try to pass data from Laravel to Vue Components.From what I find I must use axios for this but I didn't know how. I am looking for a solution for some hours now, but nothing worked. PS. I didn't do anything in blade till now. Any help, please !?
api/routes/api.php
Route::get('/content', 'ContentController#index');
ContentController
public function index() {
$customers = Customer::all();
return $customers;
}
Vue component
<template>
</template>
<script>
import axios from 'axios'
export default {
name: "Home"
};
</script>
Since you created your Vue app using the Vue CLI, running vue serve starts your application at a local URL, you need to have your Laravel API app running as well so you can request data from it using Axios in Vue components
cd api
php artisan serve
Then in your template, you should have something like this
<template>
<div></div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
databaseConfiguration: "",
errors: {}
};
},
name: "Home",
created: function() {
axios
.get("http://127.0.0.1:8000/api/content")
.then(response => {
this.databaseConfiguration = response.data;
console.log(response.data);
})
.catch(error => {
this.errors.push(error);
console.log(error);
});
}
};
</script>
Here's a full working example app on GitHub
Hope this helps