mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 14:17:22 +01:00
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:
@@ -13,8 +13,8 @@
|
||||
"async": "^1.5.0",
|
||||
"autoprefixer": "^6.4.0",
|
||||
"aws-sdk": "^2.0.25",
|
||||
"babel-loader": "^6.0.0",
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-loader": "^6.0.0",
|
||||
"babel-plugin-transform-async-to-module-method": "^6.8.0",
|
||||
"babel-polyfill": "^6.6.1",
|
||||
"babel-preset-es2015": "^6.6.0",
|
||||
@@ -108,6 +108,7 @@
|
||||
"vue": "^2.0.0-rc.6",
|
||||
"vue-hot-reload-api": "^1.2.0",
|
||||
"vue-loader": "^9.4.0",
|
||||
"vue-resource": "^1.0.2",
|
||||
"vue-router": "^2.0.0-rc.5",
|
||||
"vuex": "^2.0.0-rc.5",
|
||||
"vuex-router-sync": "^3.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable */
|
||||
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) {
|
||||
if (event.action === 'reload') {
|
||||
|
||||
@@ -86,6 +86,7 @@ var baseConfig = {
|
||||
if (!IS_PROD) {
|
||||
baseConfig.eslint = {
|
||||
formatter: require('eslint-friendly-formatter'),
|
||||
emitWarning: true,
|
||||
};
|
||||
}
|
||||
module.exports = baseConfig;
|
||||
@@ -23,7 +23,6 @@ module.exports = merge(baseWebpackConfig, {
|
||||
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoErrorsPlugin(),
|
||||
// https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
|
||||
@@ -7,4 +7,3 @@
|
||||
"html"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template lang="pug">
|
||||
#app
|
||||
site-header
|
||||
p Welcome back {{user.profile.name}}
|
||||
ul
|
||||
li
|
||||
router-link(to='/') Home
|
||||
@@ -11,15 +12,35 @@
|
||||
|
||||
<script>
|
||||
import SiteHeader from './siteHeader';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SiteHeader,
|
||||
},
|
||||
|
||||
computed: mapState(['user']),
|
||||
};
|
||||
</script>
|
||||
|
||||
<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 {
|
||||
margin: 0 auto;
|
||||
width: 80%;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template lang="pug">
|
||||
#app
|
||||
site-header
|
||||
p Welcome back {{user.profile.name}}
|
||||
ul
|
||||
li
|
||||
router-link(to='/') Home
|
||||
@@ -11,15 +12,35 @@
|
||||
|
||||
<script>
|
||||
import SiteHeader from './siteHeader';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SiteHeader,
|
||||
},
|
||||
|
||||
computed: mapState(['user']),
|
||||
};
|
||||
</script>
|
||||
|
||||
<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 {
|
||||
margin: 0 auto;
|
||||
width: 80%;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
<title>Habitica</title>
|
||||
</head>
|
||||
<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>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
|
||||
@@ -4,16 +4,37 @@ require('babel-polyfill');
|
||||
|
||||
import Vue from 'vue';
|
||||
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 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
|
||||
VuexRouterSync.sync(store, router);
|
||||
|
||||
new Vue({ // eslint-disable-line no-new
|
||||
const app = new Vue({ // eslint-disable-line no-new
|
||||
router,
|
||||
store,
|
||||
el: '#app',
|
||||
render: h => h(App),
|
||||
render: h => h(AppComponent),
|
||||
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');
|
||||
}
|
||||
});
|
||||
15
website/client/vuex/actions.js
Normal file
15
website/client/vuex/actions.js
Normal 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;
|
||||
}
|
||||
7
website/client/vuex/mutations.js
Normal file
7
website/client/vuex/mutations.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export function SET_TITLE (state, title) {
|
||||
state.title = title;
|
||||
}
|
||||
|
||||
export function SET_USER (state, userJson) {
|
||||
state.user = userJson;
|
||||
}
|
||||
@@ -1,12 +1,17 @@
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import * as mutations from './mutations';
|
||||
import * as actions from './actions';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const state = {
|
||||
title: 'Habitica',
|
||||
user: {},
|
||||
};
|
||||
|
||||
export default new Vuex.Store({
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
});
|
||||
Reference in New Issue
Block a user