laravel + vue router cannot get parameters from url - laravel-5

I try to get parameters from url
let's say url contains:
localhost:8000/blog?q=hello
I want to grab hello to trigger function call
What I had declare in app.js in laravel webpack:
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
routes: []
})
const app = new Vue({
router
});
export default app;
In blog page, I try to extract the parameter from url
new Vue ({
el: "#blog-content",
},
mounted: function() {
q = this.$route.query.q
console.log(q)
}
)
I npm run dev to compile and run the blog page it show error:
TypeError: Cannot read property 'query' of undefined
what is wrong? I am sure that Vue Router is properly installed in the application.

I think that the blog page that you use is not correct.
You recreate another Vue instance and in that case that new instance doesn't have a router passed to it. So I think that's why this.$router is undefined.
Also you don't pass the view Component to your router so it doesn't know what to look for with the specific url.
Here's your app.js file corrected
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import Blog from './views/Blog';
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/blog',
name: 'blog',
component: Blog
},
]
});
The blog view page template : views/Blog.vue
<template>
<div class="wrapper">
My blog page
</div>
</template>
<script>
export default {
data() {
return {
myvariable : ''
}
},
mounted() {
let q = this.$route.query.q;
console.log(q);
},
};
</script>
Now it should works correctly :)
Edit : Also you don't need to export the app variable in your app.js
Remove the following line export default app; at the end of the file

Related

Get data from Laravel(in api folder) to Vue (placed in another folder)

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

router not defined when calling inside a vuex action

Am using Vuex in my Laravel app and for some reason, I cannot do route.push inside an action.
My app.js:
require('./bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router'
import { routes } from './routes'
import store from './store/store'
Vue.use(VueRouter)
Vue.component('app-component', require('./App.vue').default);
Vue.component('appRegister', require('./components/User/Register.vue').default);
Vue.component('appLogin', require('./components/User/Login.vue').default);
const router = new VueRouter({
mode: 'history',
routes
})
const app = new Vue({
el: '#app',
router,
store
});
Inside my Login controller, I have a method called login which looks like the following:
login(){
this.$store.dispatch('login', this.user);
}
Then my login action looks like this:
login: ({commit}, user) => {
state.users.map(u => {
if(u.email == user.email){
router.push('/');
}
});
}
When I click on the button, I see the following error in the console:
[Vue warn]: Error in v-on handler: "ReferenceError: router is not defined"
Note, if I do the following inside the Component method, it works fine:
login(){
this.$router.push('/');
}
How can I do the route push inside the vuex action?
I looked at this answer here but it does not seem to solve my problem.
I imported vue-router inside app.js
You have to define your vue router in your login controller or import your router into your login controller.

Vue.js router view no components?

I am trying to make a vue SPA using vuex, vue-router & laravel for backend. I was separating our data on our app.js to try to reduce clutter and keep our code neat. When everything on one page it works as intended, loading the routes in the router. But when we separate the code to make it more modular into: app.js, boostrap.js, routes.js, and store.js
The components aren't loading in our router-view and we are able to see our RouterLink
app.js
// Require the bootstrapper
require('./bootstrap');
// Grab imports
import Store from './store';
import Router from './routes';
// Views
import App from './views/App';
// Create the application
const app = new Vue({
el: '#heroic',
components: { App },
store: Store,
router: Router
});
boostrap.js
// Imports
import Vue from 'vue';
import Axios from 'axios';
import Swal from 'sweetalert2';
// Add to window
window.Vue = Vue;
window.Axios = Axios;
// Add Axios headers
window.Axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.Axios.defaults.headers.common['Authorization'] = 'Bearer ' + 'token';
window.Axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
routes.js
// Imports
import Vue from 'vue';
import VueRouter from 'vue-router';
import Store from './store';
// Set to use
Vue.use(VueRouter);
// Views
import Hello from './views/Hello';
import Home from './views/Home/';
import UserIndex from './views/UserIndex';
// Create our routes
const routes = [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/hello',
name: 'hello',
component: Hello,
},
{
path: '/users',
name: 'users.index',
component: UserIndex,
}
];
// Create the router
const router = new VueRouter({
mode: 'history',
routes: routes,
scrollBehavior (to, from, saved) {
if (saved) {
return saved;
}
return { x: 0, y: 0};
}
});
// Before every request
router.beforeEach((to, from, next) => {
});
// After every request
router.afterEach((to, from, next) => {
});
// Export
export default router;
hello.vue
<template>
<div class="row row-cards row-deck">
<div class="col-lg-4 col-md-6">
<p>Hello World!</p>
</div>
</div>
</template>
store.js
// Imports
import Vue from 'vue';
import Vuex from 'vuex';
import PersistedState from 'vuex-persistedstate';
import Cookie from 'js-cookie';
// Set use
Vue.use(Vuex);
// Create our store
const store = new Vuex.Store({
state: {
auth: [{
id: 1,
username: '',
motto: '',
rank: 1,
permissions: [],
token: ''
}],
users: [],
},
mutations:{
},
actions: {
},
getters: {
}
});
// Export
export default store;
The expected result is that when I visit the "/hello" route it would show the information that says "Hello world!" that is within the Vue file specified as the component in the routes section of the router. Instead using my Vue DevTools I get the following with no Hello world on the page.
https://i.pathetic.site/chrome_99Mbxf7f0c.png
My guess is the router is stuck waiting for the beforeEach (and also possibly afterEach) hook to be resolved. You need to call next().
Also unrelated, but if you’re using modules then you shouldn’t need to assign stuff on window.

Vue Router + Laravel: Reloading a page without a 404 and passing in a route varable

When reloading my single page application, I would like the url to load correctly instead of throwing a 404 error. Using Laravel 5.6, Vue.js 2.6, & MAMP.
I have tried the following code, however, I am loading different app.js files in the same welcome view based on what the URL is. Because of this structure,, this solution is not working:
Route::get('/{vue_capture?}', function () {
return view('welcome', ['app_path' => 'load different vuejs apps here in my routes/web.php file based on the url']);
})->where('vue_capture', '[\/\w\.-]*');
I would like to have refresh work with my vue router. Any suggestions, either having to do with my routes/web.php file or .htaccess file is appreciated.
Note: This .htaccess file configuration was not working for me (apache):
https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations
//welcome blade
<div id="app">
<app></app>
</div>
<script src="{{ asset($app_path) }}"></script>
//app.vue
<div class="container-fluid px-0">
<router-view/>
</div>
Well, as far I can see, your approach was good. You are capturing all GET requests, and passing them to your Blade view.
My suggestion:
Cleaner route:
Route::get('/{any}', 'YourController#index')->where('any', '.*');
Your app.js (main JS file should look something like this):
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import App from './views/App'
import About from './views/About'
import Home from './views/Home'
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About,
},
],
});
const app = new Vue({
el: '#app',
components: { App },
router,
});
With all this configuration and your router-view, you should be fine.

Vue <template> in a .vue file with Lodash

In my .vue file within my template section I have:
<a v-bind:href="'javascript:artist(\'' + _.escape(artist) + '\')'">
which is using the Lodash function _.escape. This generates a string of errors the first of which is:
[Vue warn]: Property or method "_" is not defined on the instance but referenced during
render.
However in the same file in the script section of the component I am happily and successfully using a range of Lodash functions.
This is a Laravel app and in my app.js file I have this code:
require('./bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router';
window.Vue.use(VueRouter);
import lodash from 'lodash';
Object.defineProperty(Vue.prototype, '$lodash', { value: lodash });
import SearchHome from './components/search.vue';
const routes = [
{
path: '/',
components: {
searchHome: SearchHome
}
},
]
const router = new VueRouter({ routes })
const app = new Vue({ router }).$mount('#app')
Can anyone please help me?
Try to use a computed value instead. This will improve readability.
Avoid complex operation in a binding.
<a :href="artistLink">
And in the script
import _ from 'lodash'
export default {
computed: {
artistLink () {
return 'javascript:artist(\'' + _.escape(this.artist) + '\')'
}
}
}

Resources