Best practice for multiple Vue instances/apps in Laravel - vue.js

What I want to create is a web application with Laravel Lumen and VueJS, where Laravel Lumen is used for an API and VueJS for a SPA. In the application I want an admin section, a small forum and the website. I want to reuse this concept in future projects where I can easily decide if I want a forum or admin section in the website, or possibility to expand easily like adding a shop.
My concept idea of structure
My idea was to make three separate vue instances of the different sections inside the Lumen project.
A example of the directory structure would look as follow:
(lumen project)
├── app
├── node_modules
├── public
├── resources
│ ├── js
│ │ ├── admin
│ │ │ ├── components
│ │ │ ├── router
│ │ │ ├── store
│ │ │ ├── views
│ │ │ └── admin.js // where I create a vue instance
│ │ ├── forum
│ │ │ ├── components
│ │ │ ├── router
│ │ │ ├── store
│ │ │ ├── views
│ │ │ └── forum.js // where I create a vue instance
│ │ └── site
│ │ ├── components
│ │ ├── router
│ │ ├── store
│ │ ├── views
│ │ └── site.js // where I create a vue instance
│ ├── sass
│ │ ├── admin
│ │ ├── forum
│ │ └── site
│ └── views
├── routes
├── package.json
├── webpack.mix.js
...
With Laravel-mix the js/vue and sass files will be for each compiled to three separate files in the public folder:
const mix = require('laravel-mix');
require('laravel-mix-alias');
mix.js('resources/js/site/site.js', 'public/js')
.js('resources/js/admin/admin.js', 'public/js')
.js('resources/js/forum/forum.js', 'public/js')
.sass('resources/sass/site/site.scss', 'public/css')
.sass('resources/sass/admin/admin.scss', 'public/css')
.sass('resources/sass/forum/forum.scss', 'public/css')
.setPublicPath('public');
mix.alias({
'#': '/resources/js/site',
'#admin': '/resources/js/admin',
'#forum': '/resources/js/forum',
'~': '/resources/sass/site',
'~admin': '/resources/sass/admin',
'~forum': '/resources/sass/forum'
});
Then in the (laravel) Lumen Routes and controllers there will be decided which js, admin, site or forum, has to be included inside the Lumen View. So each section has there own Lumen View, like admin.blade.php, site.blade.php and forum.blade.php. From there on the view will be generated inside Vue and Lumen will be used as API.
My question
I wonder if I'm going a good direction before I go further, is this a good practice? What could be better, or what should be totally different? I think that an other option would be separating everything totally and create separate repositories instead of one, but I want everything as one product. I'm looking for an answer which explains what would be best practice for my situation.

Tried three years ago something similar. I'll share my experience and hope it helps:
Even if it looks good at first, you will find along the development process that your SPA's do not share as much code as you initially presume. They will diverge and they will become harder and harder to maintain as a single codebase.
After repeated failures, I've reached my perfect setup: I've identified my admin SPA to be the one I need with every project. So that one is the single one included with my Lumen API and it is built and managed as a single codebase.
The Marketing/Presentation website is a totally different project, Vue-only, created with vue-cli. Other apps (like a forum) are also separate projects.
On the long run, this allows you to:
maintain the admin template together with the API (for example, I found the user management to be something I want for 80% or my API's, so my admin template now features the CRUD operations for users)
start from a modern template and not an obsolete one for new web apps: for example, you can have the website not as a SPA Vue app but a Nuxt website. Of course, you'll be connecting to the same Lumen API.
you won't be forced to use the same layouts and CSS frameworks for your new projects.
when you identify a repetitive code fragment between your projects, you can easily add it in your starter (template) repository. It's easier to delete that to write.
But, if you decide to go with the monolithic approach, I would suggest moving the sass files alongside your SPA's, something like /resources/admin/js/components and /resources/admin/sass/base.scss.

there
My solution would look like kind of dirty or not "professional", but what i've been doing is creating something like "app-factory.js". This file what does is looking for the url on my app, for instance "/dashboard" then return all the vuejs stuff necessary for the vue application (store, vue, etc). I have another file called app.js, this file get files from app-factory.js then create the vue instance. On all my laravel view is getting this app.js (dashboard.blade.php, students.blade.php).

Related

Nuxt.js: weird behavior on two or more <nuxt-child> on same directory

in Nuxt, with this folder structure.
main
├── parent1
│ └── index.vue
├── parent2
│ └── index.vue
├── _parent1.vue
├── _parent2.vue
_parent1.vue and _parent2.vue contains <nuxt-child> tag inside and supposedly render the contents of parent1/index.vue parent2/index.vue contents respectively.
but... when accessing ~/main/parent1 and ~/main/parent2 route, both shows the content of _parent1.vue!!! or whichever component that comes first alphabetically.
is it a known bug? are there any solution to make is work as expected?
edit: added underscore to parent file

I cannot change local json file in runtime

I want to use a local json file in my app. I simply import it and use without any problem in development. But after build, it's bundled and I cannot see or change it.
I don't want it to be bundled, so I can change it while my app is working on my host.
or any other suggestion is appreciated.
<script>
import articlesJson from "./../static/articles.json";
export default {
name: "Body",
data() {
return {
articles: articlesJson
};
},
};
</script>
My dist folder after build.
.
├── css
│   ├── app.934f0703.css
│   └── chunk-vendors.e246dba9.css
├── fav.ico
├── img
│   └── profile-photo.446da51d.jpg
├── index.html
└── js
├── app.01988997.js
├── app.01988997.js.map
├── chunk-vendors.3ee1fa24.js
└── chunk-vendors.3ee1fa24.js.map
You should be able to import the data in your json file if you convert it to a .js file and declare and export your json object.
const myObject = { 'property': 'value' }
export default myObject;
Then you should be able to use it like any other module. Alternately you may need a some sort of a json loader... webpack docs
Edit
I just saw that your problem isn't importing the file but updating it. If you want your app to see the up to date version you'll need to reference that file directly rather than importing the module from the bundle. The bundle won't be updated without your repacking/deploying.
I'm not sure how you're serving your app, but in addition to referencing your json file directly, you need to make sure that file is deployed to the server rather than simply hanging out with the rest of your unbundled js which shouldn't be deployed.

Nuxt routing multiple levels

Could somebody explain how to add a multi levels (children) path using nuxt. The structure of my project is:
├root
│ ├── events
│ ├── _id.vue
│ ├── cateogries
│ └── _id.vue
Basically my links are like this:
http://localhost/events
Will display a list of events
http://localhost/events/{id}
Will display the event information plus some categories
http://localhost/events/{id}/category/{id}
Will display the event category information
I've tried doing the structure of the folders and subfolders and is not working.
I've tried to use inside _id.vue from events <nuxt-child/> and is not working.
Does anyone has any ideas how to solve this?
Thank you in advanced.
First, not duplicate id param, use other name.
you can use such a structure:
├pages
│ ├── events
│ ├── _eid
│ ├── category
| |__ index.vue
│ └── _id.vue
_id.vue for http://localhost:3000/events/2/category/5
<template>
<div>
{{ $route.params }} //{ "eid": "2", "id": "5" }
Hello from _id
</div>
</template>
For each level add index.vue or a dynamic "_".
Also be consistent in names (category or categories)

Dynamic Navigation using Vue Router?

I want to setup my Vue App to use a linear navigation structure to arrange the final html documents that I will be serving via iFrame.
.
├── School
│ ├── SQL
| | ├── SQL Basics
| | ├── SQL Intermediate
| | ├── SQL Advanced
| | └── ...
│ ├── Python
| | ├── Python Basics
| | ├── Python Data Structures
| | ├── Python Classes
| | ├── Python Advanced
| | └── ...
| └──...
└── ...
The current way I have been able to achieve with this structure is to create a Component for School, one for SQL and one for Python and have list rendering Cards for navigation. You can see that this will get tedious if I expand in the future.
I want to improve the structure to have just one Cards component dynamically generating the route and the navigation cards and the data being fed from the Vuex Store.
Working Demo
You can inject additional routes at any time, You don't have to declare up front.
You could make use of router.addRoutes so you can iterate your object of content and generate the routes on application beforeMount or beforeCreate where you would do this.$router.addRoutes(...).
https://v2.vuejs.org/v2/api/#beforeMount
https://v2.vuejs.org/v2/api/#beforeCreate
https://router.vuejs.org/api/#router-addroutes

Bootstrap - Going from basic template to more advanced examples

I think this may be offtopic but I don't know how else to ask it or where else to direct it. I'm a new web developer and I'm used to building CSS and HTML from scratch to make various tools. I wanted to make a move into a framework like Bootstrap to make things look a little more professional but I'm really struggling to understand how to use it.
I'm struggling to understand the file structure bootstrap provides and where it should live in my web server. The basic minified download consists of folders for css, fonts and js. However examples such as the jumbotron reference other files such as
<!-- Bootstrap core CSS -->
<link href="../../dist/css/bootstrap.min.css" rel="stylesheet">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<link href="../../assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="jumbotron.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="../../assets/js/ie-emulation-modes-warning.js"></script>
But I don't know where these files are supposed to live. Do I need to modify each of these href links? What should the file structure look like?
Thanks for any help.
if you look at the latest version of bootstrap getting started guide you will be able to understand the folder structure.
Bootstrap has separated out the different type of files into different folders.
bootstrap/
├── css/
│ ├── bootstrap.css
│ ├── bootstrap.css.map
│ ├── bootstrap.min.css
│ ├── bootstrap.min.css.map
│ ├── bootstrap-theme.css
│ ├── bootstrap-theme.css.map
│ ├── bootstrap-theme.min.css
│ └── bootstrap-theme.min.css.map
├── js/
│ ├── bootstrap.js
│ └── bootstrap.min.js
└── fonts/
├── glyphicons-halflings-regular.eot
├── glyphicons-halflings-regular.svg
├── glyphicons-halflings-regular.ttf
├── glyphicons-halflings-regular.woff
└── glyphicons-halflings-regular.woff2
JS file is needed in case you want to use the plugins provided by Bootstrap. if you dont want to use any plugins then you dont have to include js file.
in your example above , first file is obvious that its a bootstrap.css file. second file is fix for ie, some feature of bootstrap doesn't work in ie10. Third file is application specific file. and 4th one is for debugging purpose as said in the comments.
if you are using bower or some other tool for dependency management then all your third party dependencies should go eaither in bower_components or vendor folder. all you application specific css should reside in your app folder.
hope it helps.