1.优化样式;2.尝试加入夜晚模式,效果开发完毕开关位弄好,后期尝试加入主题颜色切换

This commit is contained in:
reco_luan 2019-04-14 13:29:01 +08:00
parent befc4d7367
commit fae6cf58ea
16 changed files with 557 additions and 22 deletions

View File

@ -47,7 +47,8 @@ export default {
data () {
return {
isSidebarOpen: false,
isHasKey: true
isHasKey: true,
nightMode: false
}
},
@ -94,7 +95,8 @@ export default {
{
'no-navbar': !this.shouldShowNavbar,
'sidebar-open': this.isSidebarOpen,
'no-sidebar': !this.shouldShowSidebar
'no-sidebar': !this.shouldShowSidebar,
'night-mode': this.nightMode
},
userPageClass
]
@ -106,6 +108,11 @@ export default {
this.isSidebarOpen = false
})
if (localStorage.getItem('nightMode')) {
document.documentElement.style.background = "#000"
this.nightMode = true
}
const keyPage = this.$site.themeConfig.keyPage
if (!keyPage) {
this.isHasKey = true

View File

@ -1,5 +1,5 @@
<template>
<div class="home">
<div class="home" :class="recoShow?'reco-show': 'reco-hide'">
<div class="hero">
<img v-if="data.heroImage" :style="heroImageStyle" :src="$withBase(data.heroImage)" alt="hero">
@ -19,12 +19,12 @@
</div>
</div>
<Content custom/>
<Content class="home-center" custom/>
<div class="footer">
<span>
<i class="iconfont reco-theme"></i>
<a target="blank" href="https://recoluan.gitlab.io/vuepress-theme-reco-doc/">vuePress-theme-reco</a>
<a target="blank" href="https://recoluan.gitlab.io/vuepress-theme-reco-doc/">VuePress-theme-reco</a>
</span>
<span>
<i class="iconfont reco-other"></i>
@ -47,6 +47,11 @@ import AccessNumber from '@theme/components/Valine/AccessNumber'
export default {
components: { NavLink, AccessNumber },
data () {
return {
recoShow: false
}
},
computed: {
year () {
return new Date().getFullYear()
@ -68,11 +73,15 @@ export default {
margin: '6rem auto 1.5rem'
}
}
},
mounted () {
this.recoShow = true
}
};
</script>
<style lang="stylus">
@require '../styles/loadMixin.styl'
.home {
padding: $navbarHeight 2rem 0;
@ -81,7 +90,9 @@ export default {
.hero {
text-align: center;
img {
background-color: $accentColor;
}
h1 {
font-size: 2.5rem;
}
@ -94,7 +105,7 @@ export default {
max-width: 35rem;
font-size: 1.6rem;
line-height: 1.3;
color: lighten($textColor, 40%);
color: lighten($textColor, 20%);
}
.action-button {
@ -106,6 +117,7 @@ export default {
border-radius: 4px;
transition: background-color 0.1s ease;
box-sizing: border-box;
load-start()
&:hover {
background-color: lighten($accentColor, 10%);
@ -138,7 +150,7 @@ export default {
}
p {
color: lighten($textColor, 25%);
color: lighten($textColor, 20%);
}
&:hover {
@ -151,6 +163,7 @@ export default {
border-top: 1px solid $borderColor;
text-align: center;
color: lighten($textColor, 25%);
load-start()
> span {
margin-left 1rem
> i {
@ -160,6 +173,59 @@ export default {
}
}
&.reco-hide {
.hero {
img {
load-start()
}
.h1 {
load-start()
}
.description {
load-start()
}
.action-button {
load-start()
}
}
.features {
load-start()
}
.home-center {
load-start()
}
.footer {
load-start()
}
}
&.reco-show {
.hero {
img {
load-end(0.08s)
}
.h1 {
load-end(0.16s)
}
.description {
load-end(0.24s)
}
.action-button {
load-end(0.32s)
}
}
.features {
load-end(0.40s)
}
.home-center {
load-end(0.48s)
}
.footer {
load-end(0.56s)
}
}
}
@media (max-width: $MQMobile) {
.home {
.features {

View File

@ -21,6 +21,7 @@
:style="linksWrapMaxWidth ? {
'max-width': linksWrapMaxWidth + 'px'
} : {}">
<Theme />
<AlgoliaSearchBox
v-if="isAlgoliaSearch"
:options="algolia"/>
@ -35,9 +36,10 @@ import AlgoliaSearchBox from '@AlgoliaSearchBox'
import SearchBox from '@SearchBox'
import SidebarButton from '@theme/components/SidebarButton.vue'
import NavLinks from '@theme/components/NavLinks.vue'
import Theme from '@theme/components/Theme'
export default {
components: { SidebarButton, NavLinks, SearchBox, AlgoliaSearchBox },
components: { SidebarButton, NavLinks, SearchBox, AlgoliaSearchBox, Theme },
data () {
return {

View File

@ -1,5 +1,5 @@
<template>
<main class="page">
<main class="page" :class="recoShow?'reco-show': 'reco-hide'">
<slot name="top"/>
<div class="page-title" v-if="!(isTimeLine)">
@ -79,6 +79,12 @@ export default {
props: ['sidebarItems'],
data () {
return {
recoShow: false
}
},
computed: {
isTimeLine () {
return this.$page.frontmatter.isTimeLine
@ -145,6 +151,10 @@ export default {
}
},
mounted () {
this.recoShow = true
},
methods: {
createEditLink (repo, docsRepo, docsDir, docsBranch, path) {
const bitbucket = /bitbucket.org/
@ -209,13 +219,15 @@ function flatten (items, res) {
<style lang="stylus">
@require '../styles/wrapper.styl'
@require '../../styles/loadMixin.styl'
.page
padding-top 6rem
padding-bottom 2rem
display block
.page-title
max-width: 740px;
margin: 6rem auto 0;
margin: 0 auto;
padding: 0rem 2.5rem;
.page-edit
@ -251,6 +263,13 @@ function flatten (items, res) {
.next
float right
.reco-hide.page {
load-start()
}
.reco-show.page {
load-end(0.08s)
}
@media (max-width: $MQMobile)
.page-title
padding: 0 1rem;

20
components/Theme/CogIcon.vue Executable file
View File

@ -0,0 +1,20 @@
<template>
<svg
aria-hidden="true"
data-prefix="fas"
data-icon="cog"
class="svg-inline--fa fa-cog fa-w-16"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<!-- eslint-disable-next-line vue/html-self-closing -->
<path fill="currentColor" d="M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"></path>
</svg>
</template>
<script>
export default {
name: 'CogIcon',
};
</script>

112
components/Theme/ThemeOptions.vue Executable file
View File

@ -0,0 +1,112 @@
<template>
<div class="theme-options">
<ul v-if="yuu.hasThemes" class="color-theme-options">
<li>
<a href="#" class="default-theme" @click.prevent="setTheme()"></a>
</li>
<li v-for="color in yuu.themes" :key="color">
<a href="#" :class="`${color}-theme`" @click.prevent="setTheme(color)"></a>
</li>
</ul>
<div v-if="!yuu.disableDarkTheme" class="dark-theme-options toggle-option">
<label for="dark-theme-toggle">Enable Dark Theme?</label>
<input id="dark-theme-toggle" v-model="darkTheme" type="checkbox" @change="toggleDarkTheme" />
</div>
<div v-if="yuu.hasThemes && !yuu.disableThemeIgnore" class="force-theme-options toggle-option">
<label for="force-theme-toggle">Ignore Forced Themes?</label>
<input id="force-theme-toggle" v-model="ignoreForcedThemes" type="checkbox" @change="toggleForcedThemes" />
</div>
</div>
</template>
<script>
import yuuConfig from './yuuConfig.js';
import themeHandler from './themeHandler.js';
export default {
name: 'ThemeOptions',
mixins: [yuuConfig, themeHandler],
data() {
return {
darkTheme: false,
ignoreForcedThemes: false,
};
},
mounted() {
if (this.yuu.disableDarkTheme !== true) {
this.darkTheme = localStorage.getItem('dark-theme') === 'true';
this.toggleDarkTheme();
}
if (this.yuu.disableThemeIgnore !== true) {
this.ignoreForcedThemes = localStorage.getItem('ignore-forced-themes') === 'true';
}
},
methods: {
toggleDarkTheme() {
if (this.darkTheme) {
document.body.classList.add('yuu-theme-dark');
return localStorage.setItem('dark-theme', true);
}
document.body.classList.remove('yuu-theme-dark');
localStorage.removeItem('dark-theme');
},
toggleForcedThemes() {
if (this.ignoreForcedThemes) {
this.setTheme(localStorage.getItem('color-theme'));
return localStorage.setItem('ignore-forced-themes', true);
}
localStorage.removeItem('ignore-forced-themes');
},
},
};
</script>
<style lang="stylus">
@import '../../styles/config.styl';
.color-theme-options {
display: flex;
justify-content: space-around;
li {
width: 33%;
text-align: center;
a {
width: 15px;
height: 15px;
border-radius: 2px;
&.default-theme {
background-color: $accentColor;
}
&.blue-theme {
background-color: $blueAccentColor;
}
&.red-theme {
background-color: $redAccentColor;
}
}
}
}
.toggle-option {
display: flex;
justify-content: space-between;
align-items: center;
label {
padding-right: 0.25em;
}
}
</style>

140
components/Theme/index.vue Executable file
View File

@ -0,0 +1,140 @@
<template>
<div v-if="showSettings" v-click-outside="hideMenu" class="user-settings">
<a class="settings-button" href="#" @click.prevent="showMenu = !showMenu">
<CogIcon class="settings-icon" />
</a>
<transition name="menu-transition" mode="out-in">
<div v-show="showMenu" class="user-settings-menu">
<ThemeOptions />
</div>
</transition>
</div>
</template>
<script>
import ClickOutside from 'vue-click-outside';
import ThemeOptions from './ThemeOptions.vue';
import CogIcon from './CogIcon.vue';
import yuuConfig from './yuuConfig.js';
export default {
name: 'UserSettings',
directives: {
'click-outside': ClickOutside,
},
components: {
CogIcon,
ThemeOptions,
},
mixins: [yuuConfig],
data() {
return {
showMenu: false,
};
},
computed: {
showSettings() {
const { yuu } = this;
return yuu.hasThemes || yuu.disableDarkTheme !== true || yuu.disableThemeIgnore !== true;
},
},
methods: {
hideMenu() {
this.showMenu = false;
},
},
};
</script>
<style lang="stylus">
@import '../../styles/config.styl';
.user-settings {
position: relative;
margin-right: 1em;
.settings-button {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
.settings-icon {
width: 18px;
}
}
.user-settings-menu {
background-color: #fff;
position: absolute;
top: 40px;
left: 50%;
min-width: 100px;
margin: 0;
padding: 1em;
border: 1px solid $borderColor;
border-radius: 4px;
transform: translateX(-50%);
z-index: 150;
&::before {
content: '';
position: absolute;
top: -7px;
left: 50%;
border-style: solid;
border-color: transparent transparent $borderColor;
border-width: 0 7px 7px;
transform: translateX(-50%);
}
&.menu-transition-enter-active,
&.menu-transition-leave-active {
transition: all 0.25s ease-in-out;
}
&.menu-transition-enter,
&.menu-transition-leave-to {
top: 50px;
opacity: 0;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
}
}
.yuu-theme-dark {
.user-settings-menu {
background-color: $darkPrimaryBg;
border-color: $darkBorderColor;
&::before {
border-bottom-color: $darkBorderColor;
}
}
}
@media (max-width: $MQMobile) {
.user-settings {
margin-right: 0;
.user-settings-menu {
left: calc(50% - 35px);
&::before {
left: calc(50% + 35px);
}
}
}
}
</style>

View File

@ -0,0 +1,46 @@
export default {
mounted() {
this.setPageTheme();
},
beforeUpdate() {
this.setPageTheme();
},
methods: {
setTheme(theme, persist = true) {
const colorThemes = this.yuu.themes || {};
if (!Array.isArray(colorThemes) || !colorThemes.length) return;
const classes = document.body.classList;
const themes = colorThemes.map(colorTheme => `yuu-theme-${colorTheme}`);
if (!theme) {
if (persist) localStorage.removeItem('color-theme');
return classes.remove(...themes);
}
if (theme && !colorThemes.includes(theme)) {
const oldTheme = localStorage.getItem('color-theme');
return this.setTheme(colorThemes.includes(oldTheme) ? oldTheme : null);
}
classes.remove(...themes.filter(t => t !== `yuu-theme-${theme}`));
classes.add(`yuu-theme-${theme}`);
if (persist) {
localStorage.setItem('color-theme', theme);
}
},
setPageTheme() {
if (this.yuu.disableThemeIgnore !== true && localStorage.getItem('ignore-forced-themes') === 'true') {
return;
}
const theme = this.$page.frontmatter.forceTheme || localStorage.getItem('color-theme');
this.setTheme(theme, false);
},
},
};

19
components/Theme/yuuConfig.js Executable file
View File

@ -0,0 +1,19 @@
export default {
data() {
return {
yuu: {},
};
},
mounted() {
const { yuu = {} } = this.$site.themeConfig;
this.yuu = {
themes: yuu.colorThemes || ['blue', 'red'],
disableDarkTheme: yuu.disableDarkTheme || false,
disableThemeIgnore: yuu.disableThemeIgnore || false,
};
this.yuu.hasThemes = Array.isArray(this.yuu.themes) && this.yuu.themes.length > 0;
},
};

View File

@ -1,6 +1,6 @@
<template>
<div class="valine-wrapper">
<div id="valine" v-show="isShowComment"></div>
<div class="valine-wrapper" v-show="isShowComment">
<div id="valine"></div>
</div>
</template>

View File

@ -26,6 +26,7 @@
"dependencies": {
"leancloud-storage": "^3.10.1",
"valine": "^1.3.4",
"@vuepress/plugin-blog": "^1.0.0-alpha.46"
"@vuepress/plugin-blog": "^1.0.0-alpha.46",
"vue-click-outside": "^1.0.7"
}
}

View File

@ -9,19 +9,19 @@
margin 1rem 0
&.tip
background-color #f3f5f7
border-color #42b983
border-color #67cc86
&.warning
background-color rgba(255,229,100,.3)
border-color darken(#ffe564, 35%)
color darken(#ffe564, 70%)
background-color #fbf0ea
border-color #fb9b5f
// color darken(#ffe564, 70%)
.custom-block-title
color darken(#ffe564, 50%)
a
color $textColor
&.danger
background-color #ffe6e6
border-color darken(red, 20%)
color darken(red, 70%)
background-color #fceaea
border-color #f26d6d
// color darken(red, 70%)
.custom-block-title
color darken(red, 40%)
a

11
styles/loadMixin.styl Normal file
View File

@ -0,0 +1,11 @@
load-start(){
transition:all .25s;
transform:translateY(-20px);
opacity 0
}
load-end($delayTime){
transform:translateY(0);
transition-delay: $delayTime
opacity 1
}

88
styles/nightMode.styl Normal file
View File

@ -0,0 +1,88 @@
$bc = #000
$fc = #9e9e9e
$bdc = #9e9e9e
$fcActive = #fff
bc() {
background-color: $bc!important
}
fc() {
color: $fc!important
}
bdc() {
border-color: $bdc!important
}
fc-active() {
color: $fcActive!important
}
.night-mode
bc()
fc()
bdc()
h1, h2, h3, h4, h5, h6, a, hr
bdc()
fc()
input
bc()
fc()
bdc()
.navbar
bc()
box-shadow: 0 2px 20px 0 rgba(255,255,255,0.4);
// border-bottom: 1px solid $bdc
.site-name, .links
bc()
fc()
.nav-links a:hover,
.nav-links a.router-link-active,
.nav-links a:hover .iconfont,
.nav-links a.router-link-active .iconfont
fc-active()
@media (min-width: 765px)
.nav-item > a:not(.external):hover,
.nav-item > a:not(.external).router-link-active
border-bottom: 2px solid $fcActive;
.dropdown-wrapper .nav-dropdown
bc()
box-shadow: 0 2px 20px 0 rgba(255,255,255,0.4);
.home
.hero
.description
fc()
.features
bdc()
.feature
h2, p
fc()
.footer
bdc()
a
fc()
.abstract-wrapper .abstract-item
background-color: lighten($bc, 20%)
.custom-block.tip, .custom-block.warning, .custom-block.danger
background-color: lighten($bc, 15%)
.pagation .pagation-list
bc()
.sidebar
bc()
bdc()
.valine-wrapper
bc()
.v .vbtn, .v .vwrap
bc()
bdc()
.v .vlist .vcard
.vhead .vsys, .vh
bdc()
bc()
.timeline-wrapper
&::after
background: $fc
.year-wrapper li
bdc()
.back-to-ceiling i
fc()

3
styles/recoConfig.styl Normal file
View File

@ -0,0 +1,3 @@
// colors
$accentColor = #424242
$textColor = #232321

View File

@ -1,3 +1,4 @@
@require './recoConfig'
@require './code'
@require './custom-blocks'
@require './arrow'
@ -112,7 +113,7 @@ h1, h2, h3, h4, h5, h6
padding-top ($navbarHeight + 1rem)
margin-bottom 0
&:first-child
margin-top -1.5rem
margin-top -6.5rem
margin-bottom 1rem
+ p, + pre, + .custom-block
margin-top 2rem