I'm simply trying to learn vuejs with laravel and cannot get the example component working.
I have created a fresh route to simply serve the vue example for now.
create.blade.php
<!DOCTYPE html>
<html>
<head>
<title>VUE</title>
</head>
<body>
<h1>example</h1>
<div id="app">
<example></example>
</div>
<script src="/js/app.js"></script>
</body>
</html>
The app.js and example.vue files are exactly as out of the box ( so i won't bother showing example.vue here
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example', require('./components/Example.vue'));
const app = new Vue({
el: '#app'
});
I have npm run watch running and it seems to have built the app files ok.
Controller and route is fine, as page is loading, but I'm getting console error as follows
app.js:1697 Uncaught TypeError: Cannot read property 'csrfToken' of
undefined
at Object.<anonymous> (app.js:1697)
at __webpack_require__ (app.js:20)
at Object.<anonymous> (app.js:778)
at __webpack_require__ (app.js:20)
at Object.<anonymous> (app.js:41430)
at __webpack_require__ (app.js:20)
at app.js:66
at app.js:69
When i click the console error in chrome it points to the line in app.js:
window.axios.defaults.headers.common['X-CSRF-TOKEN'] =
window.Laravel.csrfToken;
Is it complaining about csrftoken because I've used it as a blade template ?
How can I get it working inside laravel, just so i can play with and learn vuejs ?
The code that it is complaining about is in the resources/assets/js/bootstrap.js source, which you'll see is being referenced at the top of the app.js file. In your blade file, before you include your app.js, you can set the csrf token value.
<script>
window.Laravel.csrfToken = {{ csrf_token() }};
</script>
<script src="/js/app.js"></script>
Or, alternatively, if all you want to do is play with the example as-is, you can probably just remove that line of code from bootstrap.js. But you'll probably need it later once you start using VueJS more.
I think it's better to modify your bootstrap.js file (after axios import line) with the following:
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'X-Requested-With': 'XMLHttpRequest'
};
Related
I am using Laravel. the Frontside is developed by Blade and vue.
After Installing "vuetify". The other component which I have been using happened an error.
I don't know what is going on. the component doesn't be shown in the div.
when "const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');" is removed from mix.webpackconfig, the error from Calendar disappeared.
Is that related to installing "vuetifty"?
ERROR
[Vue warn]: Error in render: "TypeError: Cannot read property 'lang' of undefined"
found in
---> <VCalendarMonthly>
<VCalendar>
<ACalendar> at resources/js/components/ACalendar.vue
<Root>
app.js
Code
window.Vue = require('vue');
Vue.use(require('v-calendar'));
Vue.component('a-calendar', require('./components/ArticleCalendar.vue').default);
const app = new Vue({
el: '#app'
});
<script src=" {{ mix('js/app.js') }}"></script>
<div id="app">
<a-calendar url="{{ url }}"></a-calendar>
</div>
ACalendar.vue
<template>
<div>
<v-calendar v-on:dayclick="dayclick"></v-calendar>
</div>
</template>
export default {
data(){
return {
items:[
],
isLoaded : false,
isLoading : false,
isError : false,
}
},
props: {
url : String
},
}
</script>
const mix = require('laravel-mix');
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');
/*
|--------------------------------------------------------------------------
| 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.webpackConfig({
plugins: [
new VuetifyLoaderPlugin(),
],
});
mix.js('resources/js/app.js', 'public/js')
.js('resources/js/chat.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.version();
app.scss
// Fonts
#import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
#import 'variables';
// Bootstrap
#import '~bootstrap/scss/bootstrap';
When I removed mix.webpackConfig and VuetifyLoaderPlugin,The calendar component works well.
After recently applied vuetify inside laravel 7 means with vuejs, I wasn't able to configure the vuetify actual settings, but that's what I have done and it works normal now.
Also I want to mention that vuetify has almost everything like calendars, tables buttons, forms etc...
resources/sass/app.scss
// Fonts
#import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
#import 'variables';
// Icons
#import '~#mdi/font/css/materialdesignicons.min.css';
#import '~material-design-icons-iconfont/dist/material-design-icons.css';
// Bootstrap
//#import '~bootstrap/scss/bootstrap';
// Vuetify
#import '~vuetify/dist/vuetify.min.css';
Note I have left the webpack.mix.js as it is
resources/js/app.js
require('./bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router'
import Vuetify from 'vuetify';
Vue.use(VueRouter);
Vue.use(Vuetify);
import {routes} from './routes';
import App from './components/App.vue';
const app = new Vue({
el: '#app',
vuetify: new Vuetify(),
router: new VueRouter({mode: 'hash', routes}),
render: h => h(App)
});
View where components are rendering means where app id is located
//Inside head tag
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
//Inside body tag
<v-app id="app"></v-app>
<script src="{{ asset('js/app.js') }}"></script>
This way I have configured my newly vuejs project with vuetify inside laravel 7, everythings is working fine, I might have misconfigured something means there might be a good approach than mine. But for me it's working now.
I am trying to run a javascript module inline. I can't figure out how.
I am using Laravel and Webpack. I am not so technical, I just follow the docs as much as possible.
resources/assets/js/revision.js
var revision = function () {
console.log('Hell world');
};
module.exports = revision;
I run npm run dev with this webpack.mix.js
mix.js('resources/assets/revision.js', 'public/js/revision.js').version();
I have tried this url
<script type="module">
import { revision } from '/js/revision.js';
</script>
gives "The requested module '/js/revision.js' does not provide an export named 'revision'"
and
<script type="module" src="{{ asset('js/revision.js') }}"></script>
is not doing anything....
I'm using Laravel facing a problem when compiling assets. By default laravel provides a wrapper around webpack which is laravel-mix, laravel-mix using file called webpack.mix.js, and by using npm run dev command, laravel-mixcompile all js files into one webpack bundle js file.
Code of webpack.mix.js:
let mix = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
I have a Main.js file which has some jquery code.
Main.js:
;( function( $, window, document, undefined ) {
'use strict';
$(window).on('load', function() {
alert('ready');
});
}
)( jQuery, window, document );
My directory structure is something like this
resources\assets\js
app.js
bootstrap.js
Main.js
Code of app.js:
require('./bootstrap');
Code of bootstrap.js:
try {
window.$ = window.jQuery = require('jquery');// jquery
require('bootstrap');// bootstrap framework js
require('./Main'); // Main.js
} catch (e) {
}
When i type command npm run dev all assets are compile into one file then why my Main.js jquery code which is just an alert popup doesn't execute on the page.
But when i change order of the bootstrap.js file into something like this then my Main.js code is execute.
try {
window.$ = window.jQuery = require('jquery');// jquery
require('./Main'); // Main.js
require('bootstrap');// bootstrap framework js
} catch (e) {
}
Why this thing is happening. Does conflict happen between bootstrap framework js file and Main.js file.
Replying to the tldr in the comments:
There is not any error comes, but when i load my page my Main.js script is not executed
I had this same issue and including the manifest.js and vendor.js solved these issues:
<script src="{{ mix('js/manifest.js') }}"></script>
<script src="{{ mix('js/vendor.js') }}"></script>
I am trying to figure out how I will deploy a Vue SPA with a Laravel backend on Ubuntu on DigitalOcean
I am currently able to deploy Laravel apps on Digital Ocean with no problem at all. My new challenge is that I am creating an SPA with the Vue-Webpack template and using a standalone Laravel app as backend.
I am not sure how I will deploy this and structure my folders on Ubuntu.
one way is to keep your projects in /var/www/ side by side in two folders(laravel-api and vue-app). another way is placing your app contents inside laravel-app's resources folder. configure nginx or apache to serve the laravel api backend only.
see http://vuejs-templates.github.io/webpack/backend.html
update config/index.js
var path = require('path')
module.exports = {
build: {
index: path.resolve(__dirname, 'dist/index.html'),
assetsRoot: path.resolve(__dirname, 'dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
productionSourceMap: true
},
dev: {
port: 8080,
proxyTable: {}
}
}
from the docs
build.index
Must be an absolute path on your local file system.
This is where the index.html (with injected asset URLs) will be
generated.
If you are using this template with a backend-framework, you can edit
index.html accordingly and point this path to a view file rendered by
your backend app, e.g. app/views/layouts/application.html.erb for a
Rails app, or resources/views/index.blade.php for a Laravel app.
build.assetsRoot
Must be an absolute path on your local file system.
This should point to the root directory that contains all the static
assets for your app. For example, public/ for both Rails/Laravel.
What you should do is serve your main index file through Laravel routes or some other method of serving. lets say you have home.blade.php as index file
1 - show application entry point
routes.php / web.php
Route::get('/', function() {
return view('home');
});
this index file should contain the app element. then you should use vue-router for navigation which will add # after index url.
Here is how to configure javacript part
2 - Install and Import VueRouter to /resources/assets/js/bootstrap.js
3 - Use Vue router with Vue ( Vue.use(VueRouter);)
bootstrap.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
window.Vue = Vue;
Vue.use(VueRouter);
window.axios = axios;
window.axios.defaults.headers.common = {
'X-Requested-With': 'XMLHttpRequest'
};
4 - Create /resources/assets/js/routes.js file
5 - Import vue router
6 - define routes
7 - Export routes
routes.js
import VueRouter from 'vue-router';
let routes = [
{
path: '/',
component: require('./views/Home')
},
{
path: '/another',
component: require('./views/Another')
}
];
export default new VueRouter({
routes
})
8 - Create /resources/assets/js/ app.js file which would be the javascript main app
9- require the bootstrap.js and Import routes.js file we created
10 - Use it set router: router (as we are using ES6 just router as defined below would be considered as router:router)
11 - Thats the new Vue app there
app.js
require('./bootstrap');
import router from './routes';
new Vue({
el: '#app',
router
//app works go here
});
12 - Use app.js in the home.blade.php
13 - Add router links
14 - Add router view
home.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My App</title>
</head>
<body>
<div id="app">
<section class="section">
<div class="container">
<nav class="tabs is-boxed">
<div class="container">
<ul>
<router-link tag="li" to="/" exact>
<a>Home</a>
</router-link>
<router-link tag="li" to="/another">
<a>Another</a>
</router-link>
</ul>
</div>
</nav>
<router-view></router-view>
</div>
</section>
</div>
<script src="/js/app.js"></script>
</body>
</html>
15 - Remember to run webpack.
Good luck
I am assuming you have two folders for your project: client where your vue.js code goes in, and server where your backend code lives.
The short answer
Just copy the SPA build files (located in client/dist folder by default) into your server/public folder and deploy it (The same thing is true with express for Node.js).
But you can do it better
Surely you want to avoid the manual work of copying static files from client/dist to server/public on every build you do. This is easy, all you need is just changing the build folder in your client/config/index.js and make it your server/public instead of the default client/dist.
client/config/index.js:
build: {
// change "../dist" to "../../server/public" in both rules
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
}
This is the recommended way to do it as described in the webpack template guide.
Check out my new project Laravue-SPA. It's a framework that pulls together Laravel, Vue.js and Vuetify to create a single page application.
It's brand new and still pre alpha release but I'll be happy to provide support and fix bugs as they're discovered!
Plus it will introduce you to the concepts needed to create an SPA even if you go off in your own direction.
I am getting below error.
Uncaught Error: Bootstrap's JavaScript requires jQuery. jQuery must be
included before Bootstrap's JavaScript.
app.js
require('./bootstrap');
window.Vue = require('vue');
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import VueAxios from 'vue-axios';
import axios from 'axios';
Vue.use(VueAxios, axios);
import App from './App.vue';
import Login from './components/Login.vue';
import Register from './components/Register.vue';
import Activity from './components/Activity.vue';
import SelectPersons from './components/SelectPersons.vue';
const routes = [
{
name: 'Login',
path: '/',
component: Login
},
{
name: 'Register',
path: '/register',
component: Register
},
{
name: 'Activity',
path: '/activity',
component: Activity
},
{
name: 'SelectPersons',
path: '/selectpersons',
component: SelectPersons
}
];
const router = new VueRouter({ mode: 'history', routes: routes});
new Vue(Vue.util.extend({ router }, App)).$mount('#app');
bootstrap.js
window._ = require('lodash');
/**
* We'll load jQuery and the Bootstrap jQuery plugin which provides support
* for JavaScript based Bootstrap features such as modals and tabs. This
* code may be modified to fit the specific needs of your application.
*/
try {
window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');
} catch (e) {}
window.Vue = require('vue');
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Next we will register the CSRF Token as a common header with Axios so that
* all outgoing HTTP requests automatically have it attached. This is just
* a simple convenience so we don't have to attach every token manually.
*/
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
// import Echo from 'laravel-echo'
// window.Pusher = require('pusher-js');
// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: 'your-pusher-key'
// });
Here is the file that loads every vue component or blade template pages.
<html>
<head>
{{Html::style('/css/bootstrap.css')}}
{{Html::style('/css/style.css')}}
{{Html::script('/js/bootstrap.js')}}
</head>
<body>
<div id="app">
</div>
<script src="{{asset('js/app.js')}}"></script>
</body>
</html>
I am using Laravel with vue. Can anybody help me to solve this issue?
Thanks
Your app.js contains jquery. so do as the error says and load bootstrap after jquery.
<html>
<head>
{{Html::style('/css/bootstrap.css')}}
{{Html::style('/css/style.css')}}
</head>
<body>
<div id="app">
</div>
<script src="{{asset('js/app.js')}}"></script>
{{Html::script('/js/bootstrap.js')}}
</body>
</html>
Bootstrap required jQuery to run some of its features like the dropdown. the error says "Uncaught Error: Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.". So first, require the jquery library, then next is the bootstrap.min.js or bootstrap.js. Please feel free to comment if you have any problem with this. And one more thing, it is better to place your all JS files before </body>.
Try this
<html>
<head>
{{Html::style('/css/bootstrap.css')}}
{{Html::style('/css/style.css')}}
</head>
<body>
<div id="app">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
{{Html::script('/js/bootstrap.js')}}
<script src="{{asset('js/app.js')}}"></script>
</body>
</html>