Large Scale
Patterns for
Vue.js Applications
Daniel Kelly
Teacher @ Vue School
Full Stack developer (10 years)
Husband and Father
What is the best way to structure a Vue.js application?
1
The answer in a single word:
The answer in a single word:
Predictability
Feature Request
Source Code
httpRequest?
cache?
notify?
authUser?
route?
globalState?
Why is this important?
Why is this important?
A predictable codebase alleviates this experience as much a possible
Predictability:
What I'm Not Saying
2
Your codebase can be 100% predictable
Your codebase can be 100% predictable
Your codebase can be
100% understood as a whole
Your codebase can be
100% understood as a whole
How do we accomplish predictability in a codebase?
How do we accomplish predictability in a codebase?
Standards
What kind of standards exist for the
Vue community at large?
3
4 sources of standards
- The Vue.js style guide
4 sources of standards
- The Vue.js style guide
-
The scaffolding generated by
-
npm init vue@3
-
4 sources of standards
- The Vue.js style guide
-
The scaffolding generated by
-
npm init vue@3
-
- the officially recommended tooling
4 sources of standards
- The Vue.js style guide
-
The scaffolding generated by
-
npm init vue@3
-
- the officially recommended tooling
- the most popular component frameworks
Official and Component Libraries
- Primary purpose is functionality
- Side affect is shared standards
- Use the existing solution!
Vue CLI Provided
Standard File Structure
Component Standards
From the Vue.js Style Guide
Component Standards
- Dedicated SFCs
- SFCs should be PascalCase
- Prefix base components
- App
- Base
- Multi-Worded names
app-popup.vue
Component Standards
-
Prefix Single instance components
- The
-
Prefix tightly coupled child components
- TodoList and TodoListItem
- Begin with the most general
- And end with the most specific
https://vuejs.org/style-guide/
Vue.js Style Guide
Official ESLint Plugin
https://eslint.vuejs.org/
Recommended
Personal or Team-Wide Standards
4
A Flat Component Directory
Quickly navigate from Vue devtools to file
Use your IDE's quick find or file jumping feature to filter files
Remove analysis paralysis
See all your components at once
Get rid of the redundancy of keywords in filenames AND in the directory
Eliminate surfing the file structure
Simplify Importing Components
import ClientForm from '@/components/ClientForm.vue'
A Flat Component Directory
- Quickly navigate from Vue Devtools to Component File
- Encourages navigation with IDE quick find
- Remove analysis paralysis for component organization
- Remove redundancy in folder names and file names
- Eliminate file surfing
- Simplify component imports
Confession
An Almost Flat Component Structure
An Almost Flat Component Structure
Standardized
Route Naming Convention
An Almost Flat Component Structure
Standardized
Route Naming Convention
Standardized Route Naming Convention
Path | Route and Component Name | What it Does |
---|---|---|
/users | UsersIndex | List all the users |
/users/create | UsersCreate | Form to create the user |
/users/{id} | UsersShow | Display the users details |
/users/{id}/edit | UsersEdit | Form to edit the user |
A More Comprehensive File Structure
A More Comprehensive File Structure
A More Comprehensive File Structure
A More Comprehensive File Structure
A More Comprehensive File Structure
A More Comprehensive File Structure
A More Comprehensive File Structure
Other Helpful Tips
Other Helpful Tips
- Use Vuex Modules
- Interact with REST APIs with SDKs
- Wrap third party libs
Use Vuex Modules
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> `moduleA`'s state
https://vueschool.io/articles/series/how-to-structure-a-large-scale-vue-js-application/
Thank You!
Beyond Predictability
Some Miscellaneous Tips for Large Scale Apps
5
Libraries and Components
Wrap 3rd Party
{
}
Libraries and Components
Wrap 3rd Party
// Http.js
import axios from 'axios'
export default class Http{
async get(url){
const response = await axios.get(url);
return response.data;
}
// ...
}
Libraries and Components
Wrap 3rd Party
// Http.js
export default class Http{
async get(url){
const response = await fetch(url);
return await response.json();
}
// ...
}
Libraries and Components
Wrap 3rd Party
export default class Http{
async get(url){
try {
const response = await fetch(url);
return await response.json();
} catch (err) {
alert(err);
}
}
// ...
}
Libraries and Components
Wrap 3rd Party
// Http.js
import Cache from './Cache.js'
export default class Http{
async get(url){
const cached = Cache.get(url)
if(cached) return cached
const response = await fetch(url);
return await response.json();
}
// ...
}
Libraries and Components
Wrap 3rd Party
// AppIcon.vue
<template>
<FontAwesomeIcon v-if="type==='fa'" :icon="icon" />
<md_icon v-if="type=== 'md'">{{icon}}</md_icon>
</template>
<script>
export default{
props:{
type: { type: String, default: 'fa' },
icon: { type: String, required: true }
}
}
</script>
with SDKs
Interact with REST APIs
with SDKs
Interact with REST APIs
axios('https://someapi.com/posts/1')
post.find(1)
Auto Register Base Components
Auto Register Base Components
const app = createApp(App)
// Auto Register Base Components
const requireComponent = require.context('./components', true, /App[A-Z]\w+\.(vue|js)$/)
requireComponent.keys().forEach(function (fileName) {
let baseComponentConfig = requireComponent(fileName)
baseComponentConfig = baseComponentConfig.default || baseComponentConfig
const baseComponentName = baseComponentConfig.name || (
fileName
.replace(/^.+\//, '')
.replace(/\.\w+$/, '')
)
app.component(baseComponentName, baseComponentConfig)
})
app.mount('#app')
Testing
Just do it!
Vue Testing Library
https://testing-library.com/docs/vue-testing-library/intro/
Business Services
from
Business Services
from
- development
- consulting
- team training
Business Services
from
- development
- consulting
- team training
team@vueschool.io
Vue.js 3 Master Class
- Vue cli, Vue Router and Single File Components
- Modern Javascript (ES6/7/8)
- User permissions & protected routes
- Third Party Authentication
- Consuming a REST API
- Google Cloud Firestore
- Automatic code review with ESLint
The Essentials, like:
Vue.js 3 Master Class
- State management with Vuex
- User Permissions & Route Guards
- Deployments
- Creating Vue Plugins
- Code Splitting
- SEO
- Application Best Practices
Deeper Dives, like:
Video Course Subscription
Thank You!
Patterns for Large Scale Vue.js Applications
By Daniel Kelly
Patterns for Large Scale Vue.js Applications
- 1,197