Large Scale

Patterns for

Vue.js Applications

@danielkelly_io

@danielkellyio

Alabama, USA

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/

@danielkelly_io

@danielkellyio

Alabama, USA

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

@danielkelly_io

@danielkellyio

Alabama, USA

Thank You!

Patterns for Large Scale Vue.js Applications

By Daniel Kelly

Patterns for Large Scale Vue.js Applications

  • 840