perf: optimize the logic for determining whether to initialize (#495)

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/496/head
Ryan Wang 2022-03-09 14:22:31 +08:00 committed by GitHub
parent 54e5f3829a
commit 0faacf4d82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 38 deletions

View File

@ -2,7 +2,6 @@ import router from '@/router'
import store from '@/store' import store from '@/store'
import NProgress from 'nprogress' import NProgress from 'nprogress'
import { domTitle, setDocumentTitle } from '@/utils/domUtil' import { domTitle, setDocumentTitle } from '@/utils/domUtil'
import apiClient from '@/utils/api-client'
NProgress.configure({ showSpinner: false, speed: 500 }) NProgress.configure({ showSpinner: false, speed: 500 })
@ -11,24 +10,41 @@ const whiteList = ['Login', 'Install', 'NotFound', 'ResetPassword'] // no redire
let progressTimer = null let progressTimer = null
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
onProgressTimerDone() onProgressTimerDone()
progressTimer = setTimeout(() => { progressTimer = setTimeout(() => {
NProgress.start() NProgress.start()
}, 250) }, 250)
// set title meta
to.meta && typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title} - ${domTitle}`) to.meta && typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title} - ${domTitle}`)
// check installation status
if (store.getters.isInstalled === undefined) {
await store.dispatch('fetchIsInstalled')
}
if (!store.getters.isInstalled && to.name !== 'Install') {
next({
name: 'Install'
})
onProgressTimerDone()
return
}
if (store.getters.isInstalled && to.name === 'Install') {
next({
name: 'Login'
})
onProgressTimerDone()
return
}
if (store.getters.token) { if (store.getters.token) {
if (to.name === 'Install') { if (!store.getters.options) {
next() await store.dispatch('refreshOptionsCache').then()
return
} }
const response = await apiClient.isInstalled()
if (!response.data) { if (['Login', 'Install'].includes(to.name)) {
next({
name: 'Install'
})
onProgressTimerDone()
return
}
if (to.name === 'Login') {
next({ next({
name: 'Dashboard' name: 'Dashboard'
}) })
@ -36,10 +52,8 @@ router.beforeEach(async (to, from, next) => {
return return
} }
if (!store.getters.options) {
store.dispatch('refreshOptionsCache').then()
}
next() next()
onProgressTimerDone()
return return
} }
@ -48,6 +62,7 @@ router.beforeEach(async (to, from, next) => {
next() next()
return return
} }
next({ next({
name: 'Login', name: 'Login',
query: { query: {

View File

@ -5,6 +5,7 @@ const getters = {
layoutSetting: state => state.app.layoutSetting, layoutSetting: state => state.app.layoutSetting,
sidebar: state => state.app.sidebar, sidebar: state => state.app.sidebar,
loginModal: state => state.app.loginModal, loginModal: state => state.app.loginModal,
isInstalled: state => state.app.isInstalled,
token: state => state.user.token, token: state => state.user.token,
user: state => state.user.user, user: state => state.user.user,
options: state => state.option.options options: state => state.option.options

View File

@ -10,6 +10,7 @@ import {
LAYOUT_SETTING, LAYOUT_SETTING,
SIDEBAR_TYPE SIDEBAR_TYPE
} from '@/store/mutation-types' } from '@/store/mutation-types'
import apiClient from '@/utils/api-client'
const app = { const app = {
state: { state: {
@ -23,7 +24,8 @@ const app = {
autoHideHeader: false, autoHideHeader: false,
color: null, color: null,
layoutSetting: false, layoutSetting: false,
loginModal: false loginModal: false,
isInstalled: undefined
}, },
mutations: { mutations: {
SET_SIDEBAR_TYPE: (state, type) => { SET_SIDEBAR_TYPE: (state, type) => {
@ -67,9 +69,25 @@ const app = {
}, },
TOGGLE_LOGIN_MODAL: (state, show) => { TOGGLE_LOGIN_MODAL: (state, show) => {
state.loginModal = show state.loginModal = show
},
SET_IS_INSTALLED: (state, isInstalled) => {
state.isInstalled = isInstalled
} }
}, },
actions: { actions: {
fetchIsInstalled({ commit }) {
return new Promise((resolve, reject) => {
apiClient
.isInstalled()
.then(response => {
commit('SET_IS_INSTALLED', response.data)
resolve(response)
})
.catch(error => {
reject(error)
})
})
},
setSidebar({ commit }, type) { setSidebar({ commit }, type) {
commit('SET_SIDEBAR_TYPE', type) commit('SET_SIDEBAR_TYPE', type)
}, },

View File

@ -18,7 +18,7 @@ const keys = [
] ]
const option = { const option = {
state: { state: {
options: [] options: undefined
}, },
mutations: { mutations: {
SET_OPTIONS: (state, options) => { SET_OPTIONS: (state, options) => {

View File

@ -14,8 +14,8 @@
<!-- Blogger info --> <!-- Blogger info -->
<div class="mt-5 mb-5"> <div class="mt-5 mb-5">
<a-radio-group v-model="installationMode"> <a-radio-group v-model="installationMode">
<a-radio-button value="new"> 全新安装 </a-radio-button> <a-radio-button value="new"> 全新安装</a-radio-button>
<a-radio-button value="import"> 数据导入 </a-radio-button> <a-radio-button value="import"> 数据导入</a-radio-button>
</a-radio-group> </a-radio-group>
</div> </div>
<a-form-model <a-form-model
@ -26,7 +26,7 @@
class="installationForm animated fadeIn" class="installationForm animated fadeIn"
layout="horizontal" layout="horizontal"
> >
<a-divider dashed orientation="left"> 管理员信息 </a-divider> <a-divider dashed orientation="left"> 管理员信息</a-divider>
<a-form-model-item prop="username"> <a-form-model-item prop="username">
<a-input v-model="form.model.username" placeholder="用户名"> <a-input v-model="form.model.username" placeholder="用户名">
<a-icon slot="prefix" style="color: rgba(0, 0, 0, 0.25)" type="user" /> <a-icon slot="prefix" style="color: rgba(0, 0, 0, 0.25)" type="user" />
@ -52,7 +52,7 @@
<a-icon slot="prefix" style="color: rgba(0, 0, 0, 0.25)" type="lock" /> <a-icon slot="prefix" style="color: rgba(0, 0, 0, 0.25)" type="lock" />
</a-input> </a-input>
</a-form-model-item> </a-form-model-item>
<a-divider dashed orientation="left"> 站点信息 </a-divider> <a-divider dashed orientation="left"> 站点信息</a-divider>
<a-form-model-item prop="url"> <a-form-model-item prop="url">
<a-input v-model="form.model.url" placeholder="博客地址"> <a-input v-model="form.model.url" placeholder="博客地址">
<a-icon slot="prefix" style="color: rgba(0, 0, 0, 0.25)" type="link" /> <a-icon slot="prefix" style="color: rgba(0, 0, 0, 0.25)" type="link" />
@ -169,7 +169,6 @@ export default {
} }
}, },
beforeMount() { beforeMount() {
this.handleVerifyIsInstall()
this.$set(this.form.model, 'url', window.location.protocol + '//' + window.location.host) this.$set(this.form.model, 'url', window.location.protocol + '//' + window.location.host)
}, },
computed: { computed: {
@ -181,13 +180,7 @@ export default {
} }
}, },
methods: { methods: {
...mapActions(['installCleanToken']), ...mapActions(['installCleanToken', 'fetchIsInstalled']),
async handleVerifyIsInstall() {
const response = await apiClient.isInstalled()
if (response.data) {
await this.$router.push({ name: 'Login' })
}
},
handleInstall() { handleInstall() {
this.$refs.installationForm.validate(valid => { this.$refs.installationForm.validate(valid => {
if (valid) { if (valid) {
@ -203,6 +196,7 @@ export default {
setTimeout(() => { setTimeout(() => {
this.form.installing = false this.form.installing = false
}, 400) }, 400)
this.fetchIsInstalled()
}) })
} }
}) })
@ -241,6 +235,7 @@ export default {
setTimeout(() => { setTimeout(() => {
this.form.importing = false this.form.importing = false
}, 400) }, 400)
this.fetchIsInstalled()
}) })
}, },
handleImportCallback() { handleImportCallback() {

View File

@ -16,7 +16,6 @@
import { mapActions } from 'vuex' import { mapActions } from 'vuex'
import LoginForm from '@/components/Login/LoginForm' import LoginForm from '@/components/Login/LoginForm'
import apiClient from '@/utils/api-client'
export default { export default {
components: { components: {
@ -28,7 +27,6 @@ export default {
} }
}, },
beforeMount() { beforeMount() {
this.handleVerifyIsInstall()
document.addEventListener('keydown', this.onRegisterResetPasswordKeydown) document.addEventListener('keydown', this.onRegisterResetPasswordKeydown)
}, },
beforeDestroy() { beforeDestroy() {
@ -44,12 +42,6 @@ export default {
this.resetPasswordButtonVisible = !this.resetPasswordButtonVisible this.resetPasswordButtonVisible = !this.resetPasswordButtonVisible
} }
}, },
async handleVerifyIsInstall() {
const response = await apiClient.isInstalled()
if (!response.data) {
await this.$router.push({ name: 'Install' })
}
},
onLoginSucceed() { onLoginSucceed() {
// Refresh the user info // Refresh the user info
this.refreshUserCache() this.refreshUserCache()