├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
└── src
├── App.vue
├── assets
├── .gitkeep
├── banner.jpg
└── screen.png
├── components
└── Banner.vue
├── main.js
├── router
├── index.js
└── routes.js
├── services
├── index.js
└── users.js
├── store
├── index.js
├── modules
│ ├── Users.js
│ └── index.js
└── root.js
├── utils
├── enum.js
├── localStorage.js
└── request.js
└── views
└── Home.vue
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not ie <= 8
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | end_of_line = lf
5 | trim_trailing_whitespace = true
6 | insert_final_newline = true
7 | max_line_length = 100
8 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | browser: true,
5 | },
6 | extends: [
7 | 'plugin:vue/recommended',
8 | '@vue/airbnb',
9 | ],
10 | plugins: [
11 | 'vue',
12 | ],
13 | rules: {
14 | 'prefer-destructuring': 'off',
15 | camelcase: 'error',
16 | 'no-new': 'error',
17 | 'no-unused-vars': 'error',
18 | 'max-len': ['error', { code: 100 }],
19 | 'import/no-dynamic-require': 'allow',
20 | 'no-console': 'error',
21 | 'padded-blocks': ['error', 'never'],
22 | 'no-unused-expressions': 'error',
23 | // allow optionalDependencies
24 | 'import/no-extraneous-dependencies': ['error', {
25 | optionalDependencies: ['test/unit/index.js'],
26 | }],
27 | // disallow reassignment of function parameters
28 | // disallow parameter object manipulation except for specific exclusions
29 | 'no-param-reassign': ['error', {
30 | props: true,
31 | ignorePropertyModificationsFor: [
32 | 'state', // for vuex state
33 | 'acc', // for reduce accumulators
34 | 'e', // for e.returnvalue
35 | 'Vue', // for Vue.prototype
36 | 'config',
37 | ],
38 | }],
39 | 'no-plusplus': 'off',
40 | 'comma-dangle': ['error', 'always-multiline'],
41 | semi: ['error', 'always'],
42 | 'no-confusing-arrow': 'off',
43 | 'arrow-parens': 'off',
44 | 'consistent-return': 'off',
45 | 'no-alert': 'off',
46 | 'no-underscore-dangle': 'off',
47 | 'import/prefer-default-export': 'off',
48 | 'import/extensions': ['error', 'always', {
49 | js: 'never',
50 | vue: 'never',
51 | }],
52 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
53 | },
54 | parserOptions: {
55 | parser: 'babel-eslint',
56 | },
57 | };
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Vue Architecture Boilerplate
4 |
5 |
6 | Vue.js architecture for front-end projects.
7 |
8 |
9 |
10 | 
11 |
12 | ### Project setup
13 |
14 | ```sh
15 | # Install Deps
16 | npm install
17 |
18 | # Compiles and hot-reloads for development
19 | npm run serve
20 |
21 | # Compiles and minifies for production
22 | npm run build
23 | ```
24 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app',
4 | ],
5 | };
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-architecture-boilerplate",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "axios": "^0.18.1",
12 | "vue": "^2.6.6",
13 | "vue-router": "^3.0.1",
14 | "vuex": "^3.0.1"
15 | },
16 | "devDependencies": {
17 | "@vue/cli-plugin-babel": "^3.4.0",
18 | "@vue/cli-plugin-eslint": "^3.4.0",
19 | "@vue/cli-service": "^3.4.0",
20 | "@vue/eslint-config-airbnb": "^4.0.0",
21 | "babel-eslint": "^10.0.1",
22 | "eslint": "^5.8.0",
23 | "eslint-plugin-vue": "^5.0.0",
24 | "fibers": "^3.1.1",
25 | "lint-staged": "^8.1.0",
26 | "sass": "^1.16.0",
27 | "sass-loader": "^7.1.0",
28 | "vue-template-compiler": "^2.5.21"
29 | },
30 | "gitHooks": {
31 | "pre-commit": "lint-staged"
32 | },
33 | "lint-staged": {
34 | "*.js": [
35 | "vue-cli-service lint",
36 | "git add"
37 | ],
38 | "*.vue": [
39 | "vue-cli-service lint",
40 | "git add"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IgorHalfeld/vue-architecture-boilerplate/c49f9d40295a27c56f7781540187e7b64a93d8e7/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Vue Architecture Boilerplate
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
25 |
--------------------------------------------------------------------------------
/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IgorHalfeld/vue-architecture-boilerplate/c49f9d40295a27c56f7781540187e7b64a93d8e7/src/assets/.gitkeep
--------------------------------------------------------------------------------
/src/assets/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IgorHalfeld/vue-architecture-boilerplate/c49f9d40295a27c56f7781540187e7b64a93d8e7/src/assets/banner.jpg
--------------------------------------------------------------------------------
/src/assets/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IgorHalfeld/vue-architecture-boilerplate/c49f9d40295a27c56f7781540187e7b64a93d8e7/src/assets/screen.png
--------------------------------------------------------------------------------
/src/components/Banner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Vue Architecture Boilerplate
5 |
6 |
7 | Vue.js architecture for front-end projects
8 |
9 |
10 |
11 |
12 |
17 |
18 |
61 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 |
3 | import App from './App';
4 | import router from './router';
5 | import store from './store';
6 |
7 | Vue.config.productionTip = false;
8 |
9 | new Vue({
10 | router,
11 | store,
12 | render: h => h(App),
13 | }).$mount('#app');
14 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Router from 'vue-router';
3 | import routes from './routes';
4 |
5 | Vue.use(Router);
6 |
7 | export default new Router({
8 | mode: 'history',
9 | base: process.env.BASE_URL,
10 | routes,
11 | });
12 |
--------------------------------------------------------------------------------
/src/router/routes.js:
--------------------------------------------------------------------------------
1 | import Home from '../views/Home';
2 |
3 | export default [
4 | {
5 | path: '/',
6 | name: 'home',
7 | component: Home,
8 | },
9 | ];
10 |
--------------------------------------------------------------------------------
/src/services/index.js:
--------------------------------------------------------------------------------
1 | import users from './users';
2 |
3 | export { users };
4 |
--------------------------------------------------------------------------------
/src/services/users.js:
--------------------------------------------------------------------------------
1 | import { HTTPClient } from '../utils/request';
2 |
3 | export default {
4 | create: ({ payload }) => HTTPClient.post('/users', payload),
5 | };
6 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 |
4 | import modules from './modules';
5 | import rootStore from './root';
6 |
7 | Vue.use(Vuex);
8 |
9 | export default new Vuex.Store({
10 | modules,
11 | ...rootStore,
12 | });
13 |
--------------------------------------------------------------------------------
/src/store/modules/Users.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {},
4 | actions: {},
5 | mutations: {},
6 | getters: {},
7 | };
8 |
--------------------------------------------------------------------------------
/src/store/modules/index.js:
--------------------------------------------------------------------------------
1 | import Users from './Users';
2 |
3 | export default {
4 | Users,
5 | };
6 |
--------------------------------------------------------------------------------
/src/store/root.js:
--------------------------------------------------------------------------------
1 | import { parseNetworkError } from '../utils/request';
2 | import * as apiMethods from '../services';
3 |
4 | export const SET_API_CALL_IN_PROGRESS = 'SET_API_CALL_IN_PROGRESS';
5 | export const SET_GENERAL_ERRORS = 'SET_GENERAL_ERRORS';
6 |
7 | export default {
8 | state: {
9 | isAPICallInProgress: false,
10 | generalErrors: [],
11 | },
12 | mutations: {
13 | [SET_API_CALL_IN_PROGRESS]: (state, status) => {
14 | state.isAPICallInProgress = status;
15 | },
16 | [SET_GENERAL_ERRORS]: (state, error) => {
17 | state.generalErrors.push(error);
18 | },
19 | },
20 | actions: {
21 | /**
22 | * Dispatch AJAX calls
23 | * @param {String} entity e.g. `users`
24 | * @param {String} action method name eg. `getById`
25 | */
26 | async api({ commit }, {
27 | entity, action, payload = {}, query, params,
28 | }) {
29 | try {
30 | const response = await apiMethods[entity][action]({ payload, query, params });
31 | return response;
32 | } catch (error) {
33 | const errorPayload = { [`${entity}_${action}_request`]: parseNetworkError(error) };
34 | commit(SET_GENERAL_ERRORS, errorPayload);
35 | }
36 | },
37 | },
38 | };
39 |
--------------------------------------------------------------------------------
/src/utils/enum.js:
--------------------------------------------------------------------------------
1 | export const DEFAULT_API_URLS = {
2 | LOCAL: '',
3 | PRODUCTION: '',
4 | DEVELOPMENT: '',
5 | };
6 |
--------------------------------------------------------------------------------
/src/utils/localStorage.js:
--------------------------------------------------------------------------------
1 | const { stringify, parse } = JSON;
2 |
3 | export const setStorage = (key, value, { format } = {}) => {
4 | if (!window) return;
5 | window.localStorage.setItem(key, format ? stringify(value) : value);
6 | };
7 |
8 | export const getStorage = (key, { format } = {}) => {
9 | if (!window) return;
10 | const value = window.localStorage.getItem(key);
11 | return format
12 | ? parse(window.localStorage.getItem(key))
13 | : value;
14 | };
15 |
--------------------------------------------------------------------------------
/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import { DEFAULT_API_URLS } from './enum';
3 | import { getStorage } from './localStorage';
4 |
5 | import store from '../store';
6 | import { SET_API_CALL_IN_PROGRESS } from '../store/root';
7 |
8 | const { stringify, parse } = JSON;
9 | export const parseNetworkError = error => parse(stringify(error));
10 |
11 | const withBaseURLContext = () => process.env.NODE_ENV
12 | ? DEFAULT_API_URLS[process.env.NODE_ENV.toUpperCase()]
13 | : DEFAULT_API_URLS.development;
14 |
15 | const HTTPClient = axios.create({
16 | baseURL: withBaseURLContext(),
17 | });
18 |
19 | HTTPClient.interceptors.request.use(config => {
20 | store.commit(SET_API_CALL_IN_PROGRESS, true);
21 |
22 | const token = getStorage('token');
23 | if (token) {
24 | config.headers.common.Authorization = `Bearer ${token}`;
25 | }
26 |
27 | return config;
28 | }, response => Promise.reject(response));
29 |
30 | HTTPClient.interceptors.response.use(response => {
31 | store.commit(SET_API_CALL_IN_PROGRESS, false);
32 | return response;
33 | }, error => Promise.reject(error));
34 |
35 | export { HTTPClient };
36 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
22 |
--------------------------------------------------------------------------------