Vuex Structure (#8054)

* wip: vuex structure

* add missing files

* client: do not fail dev build on eslint error

* eslint does not block compilation, mount app when data is ready

* eslintrc.js -> eslintrc
This commit is contained in:
Matteo Pagliazzi
2016-09-23 19:49:11 +02:00
committed by GitHub
parent 5480157977
commit d3371e323e
12 changed files with 102 additions and 10 deletions

View File

@@ -13,8 +13,8 @@
"async": "^1.5.0", "async": "^1.5.0",
"autoprefixer": "^6.4.0", "autoprefixer": "^6.4.0",
"aws-sdk": "^2.0.25", "aws-sdk": "^2.0.25",
"babel-loader": "^6.0.0",
"babel-core": "^6.0.0", "babel-core": "^6.0.0",
"babel-loader": "^6.0.0",
"babel-plugin-transform-async-to-module-method": "^6.8.0", "babel-plugin-transform-async-to-module-method": "^6.8.0",
"babel-polyfill": "^6.6.1", "babel-polyfill": "^6.6.1",
"babel-preset-es2015": "^6.6.0", "babel-preset-es2015": "^6.6.0",
@@ -108,6 +108,7 @@
"vue": "^2.0.0-rc.6", "vue": "^2.0.0-rc.6",
"vue-hot-reload-api": "^1.2.0", "vue-hot-reload-api": "^1.2.0",
"vue-loader": "^9.4.0", "vue-loader": "^9.4.0",
"vue-resource": "^1.0.2",
"vue-router": "^2.0.0-rc.5", "vue-router": "^2.0.0-rc.5",
"vuex": "^2.0.0-rc.5", "vuex": "^2.0.0-rc.5",
"vuex-router-sync": "^3.0.0", "vuex-router-sync": "^3.0.0",

View File

@@ -1,6 +1,6 @@
/* eslint-disable */ /* eslint-disable */
require('eventsource-polyfill') require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true&overlay=false')
hotClient.subscribe(function (event) { hotClient.subscribe(function (event) {
if (event.action === 'reload') { if (event.action === 'reload') {

View File

@@ -86,6 +86,7 @@ var baseConfig = {
if (!IS_PROD) { if (!IS_PROD) {
baseConfig.eslint = { baseConfig.eslint = {
formatter: require('eslint-friendly-formatter'), formatter: require('eslint-friendly-formatter'),
emitWarning: true,
}; };
} }
module.exports = baseConfig; module.exports = baseConfig;

View File

@@ -23,7 +23,6 @@ module.exports = merge(baseWebpackConfig, {
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.optimize.OccurenceOrderPlugin(), new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(), new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin // https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
filename: 'index.html', filename: 'index.html',

View File

@@ -6,5 +6,4 @@
"plugins": [ "plugins": [
"html" "html"
] ]
} }

View File

@@ -1,6 +1,7 @@
<template lang="pug"> <template lang="pug">
#app #app
site-header site-header
p Welcome back {{user.profile.name}}
ul ul
li li
router-link(to='/') Home router-link(to='/') Home
@@ -11,15 +12,35 @@
<script> <script>
import SiteHeader from './siteHeader'; import SiteHeader from './siteHeader';
import { mapState } from 'vuex';
export default { export default {
components: { components: {
SiteHeader, SiteHeader,
}, },
computed: mapState(['user']),
}; };
</script> </script>
<style> <style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#loading-screen { /* outside Vue because can't wait for rendering to finish */
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #fff;
z-index: 10001;
}
#app { #app {
margin: 0 auto; margin: 0 auto;
width: 80%; width: 80%;

View File

@@ -1,6 +1,7 @@
<template lang="pug"> <template lang="pug">
#app #app
site-header site-header
p Welcome back {{user.profile.name}}
ul ul
li li
router-link(to='/') Home router-link(to='/') Home
@@ -11,15 +12,35 @@
<script> <script>
import SiteHeader from './siteHeader'; import SiteHeader from './siteHeader';
import { mapState } from 'vuex';
export default { export default {
components: { components: {
SiteHeader, SiteHeader,
}, },
computed: mapState(['user']),
}; };
</script> </script>
<style> <style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#loading-screen { /* outside Vue because can't wait for rendering to finish */
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #fff;
z-index: 10001;
}
#app { #app {
margin: 0 auto; margin: 0 auto;
width: 80%; width: 80%;

View File

@@ -5,6 +5,8 @@
<title>Habitica</title> <title>Habitica</title>
</head> </head>
<body> <body>
<!-- #loading-screen needs to be rendered before vue, will be deleted once app is loaded -->
<div id="loading-screen">Loading...</div>
<div id="app"></div> <div id="app"></div>
<!-- built files will be auto injected --> <!-- built files will be auto injected -->
</body> </body>

View File

@@ -4,16 +4,37 @@ require('babel-polyfill');
import Vue from 'vue'; import Vue from 'vue';
import VuexRouterSync from 'vuex-router-sync'; import VuexRouterSync from 'vuex-router-sync';
import App from './components/app'; import VueResource from 'vue-resource';
import AppComponent from './components/app';
import router from './router'; import router from './router';
import store from './vuex/store'; import store from './vuex/store';
Vue.use(VueResource);
Vue.http.headers.common['x-api-user'] = '';
Vue.http.headers.common['x-api-key'] = '';
// Sync Vuex and Router // Sync Vuex and Router
VuexRouterSync.sync(store, router); VuexRouterSync.sync(store, router);
new Vue({ // eslint-disable-line no-new const app = new Vue({ // eslint-disable-line no-new
router, router,
store, store,
el: '#app', render: h => h(AppComponent),
render: h => h(App), mounted () { // Remove the loading screen when the app is mounted
}); let loadingScreen = document.getElementById('loading-screen');
if (loadingScreen) document.body.removeChild(loadingScreen);
},
});
// Setup listener for title that is outside Vue's scope
store.watch(state => state.title, (title) => {
document.title = title;
});
// Mount the app when the user is loaded
let userWatcher = store.watch(state => state.user, (user) => {
if (user && user._id) {
userWatcher(); // remove the watcher
app.$mount('#app');
}
});

View File

@@ -0,0 +1,15 @@
import Vue from 'vue';
export function setTitle (store, title) {
store.commit('SET_TITLE', title);
}
export function fetchUser (store) {
let promise = Vue.http.get('/api/v3/user');
promise.then(response => {
store.commit('SET_USER', response.body.data);
});
return promise;
}

View File

@@ -0,0 +1,7 @@
export function SET_TITLE (state, title) {
state.title = title;
}
export function SET_USER (state, userJson) {
state.user = userJson;
}

View File

@@ -1,12 +1,17 @@
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import * as mutations from './mutations';
import * as actions from './actions';
Vue.use(Vuex); Vue.use(Vuex);
const state = { const state = {
title: 'Habitica', title: 'Habitica',
user: {},
}; };
export default new Vuex.Store({ export default new Vuex.Store({
state, state,
mutations,
actions,
}); });