优化代码
This commit is contained in:
522
src/App.vue
522
src/App.vue
@@ -1,307 +1,321 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
|
||||||
<!-- 加载动画 -->
|
|
||||||
<div v-show="config.loading.subPage" class="loading-bar">
|
|
||||||
<div class="bar-content"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 内容区域 -->
|
|
||||||
<el-container>
|
|
||||||
|
|
||||||
<!-- Header -->
|
|
||||||
<el-header class="main-header shadow-1">
|
|
||||||
|
|
||||||
<!-- LOGO -->
|
|
||||||
<div class="logo"></div>
|
|
||||||
|
|
||||||
<!-- 菜单 -->
|
|
||||||
<el-menu class="menu" :default-active="headerDefaultActive" mode="horizontal" router>
|
|
||||||
|
|
||||||
<!-- 标题 -->
|
|
||||||
<el-menu-item v-show="config.storage.showSiteTitle"
|
|
||||||
index="title" class="title" disabled
|
|
||||||
>Frost 网址导航</el-menu-item>
|
|
||||||
|
|
||||||
<!-- 菜单项 -->
|
|
||||||
<el-menu-item v-for="item in headerMenuItems" :key="item.id"
|
|
||||||
class="item-normal" :index="item.id" :route="{ name: item.routeName }"
|
|
||||||
>{{ item.label }}</el-menu-item>
|
|
||||||
|
|
||||||
<!-- 切换下拉菜单 -->
|
|
||||||
<el-menu-item :class="['item-dropdown', { active: showHeaderDropdown }]"
|
|
||||||
@click="showHeaderDropdown = !showHeaderDropdown"
|
|
||||||
>
|
|
||||||
<i class="fa fa-bars"></i>
|
|
||||||
</el-menu-item>
|
|
||||||
|
|
||||||
</el-menu>
|
|
||||||
|
|
||||||
</el-header>
|
|
||||||
|
|
||||||
<!-- 下拉菜单 -->
|
|
||||||
<el-menu :class="['header-dropdown', 'shadow-2', { show: showHeaderDropdown }]"
|
|
||||||
:default-active="headerDefaultActive" router
|
|
||||||
>
|
|
||||||
|
|
||||||
<!-- 菜单项 -->
|
|
||||||
<el-menu-item v-for="item in headerMenuItems" :key="item.id"
|
|
||||||
class="item-normal" :index="item.id" :route="{ name: item.routeName }"
|
|
||||||
>{{ item.label }}</el-menu-item>
|
|
||||||
|
|
||||||
</el-menu>
|
|
||||||
|
|
||||||
<!-- Container -->
|
|
||||||
<keep-alive>
|
|
||||||
<router-view class="main-container" />
|
|
||||||
</keep-alive>
|
|
||||||
|
|
||||||
</el-container>
|
|
||||||
|
|
||||||
<!-- 悬浮按钮 -->
|
|
||||||
<FloatingBtn />
|
|
||||||
|
|
||||||
|
<!-- 加载动画 -->
|
||||||
|
<div v-show="config.loading.subPage" class="loading-bar">
|
||||||
|
<div class="bar-content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 内容区域 -->
|
||||||
|
<el-container>
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
|
<el-header class="main-header shadow-1">
|
||||||
|
|
||||||
|
<!-- LOGO -->
|
||||||
|
<div class="logo"></div>
|
||||||
|
|
||||||
|
<!-- 菜单 -->
|
||||||
|
<el-menu class="menu" :default-active="headerDefaultActive" mode="horizontal" router>
|
||||||
|
|
||||||
|
<!-- 标题 -->
|
||||||
|
<el-menu-item
|
||||||
|
v-show="config.storage.showSiteTitle"
|
||||||
|
index="title"
|
||||||
|
class="title"
|
||||||
|
disabled
|
||||||
|
>Frost 网址导航</el-menu-item>
|
||||||
|
|
||||||
|
<!-- 菜单项 -->
|
||||||
|
<el-menu-item
|
||||||
|
v-for="item in headerMenuItems"
|
||||||
|
:key="item.id"
|
||||||
|
class="item-normal"
|
||||||
|
:index="item.id"
|
||||||
|
:route="{ name: item.routeName }"
|
||||||
|
>{{ item.label }}</el-menu-item>
|
||||||
|
|
||||||
|
<!-- 切换下拉菜单 -->
|
||||||
|
<el-menu-item
|
||||||
|
:class="['item-dropdown', { active: showHeaderDropdown }]"
|
||||||
|
@click="showHeaderDropdown = !showHeaderDropdown"
|
||||||
|
>
|
||||||
|
<i class="fa fa-bars"></i>
|
||||||
|
</el-menu-item>
|
||||||
|
|
||||||
|
</el-menu>
|
||||||
|
|
||||||
|
</el-header>
|
||||||
|
|
||||||
|
<!-- 下拉菜单 -->
|
||||||
|
<el-menu
|
||||||
|
:class="['header-dropdown', 'shadow-2', { show: showHeaderDropdown }]"
|
||||||
|
:default-active="headerDefaultActive"
|
||||||
|
router
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- 菜单项 -->
|
||||||
|
<el-menu-item
|
||||||
|
v-for="item in headerMenuItems"
|
||||||
|
:key="item.id"
|
||||||
|
class="item-normal"
|
||||||
|
:index="item.id"
|
||||||
|
:route="{ name: item.routeName }"
|
||||||
|
>{{ item.label }}</el-menu-item>
|
||||||
|
|
||||||
|
</el-menu>
|
||||||
|
|
||||||
|
<!-- Container -->
|
||||||
|
<keep-alive>
|
||||||
|
<router-view class="main-container" />
|
||||||
|
</keep-alive>
|
||||||
|
|
||||||
|
</el-container>
|
||||||
|
|
||||||
|
<!-- 悬浮按钮 -->
|
||||||
|
<FloatingBtn />
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FloatingBtn from '@/components/FloatingBtn.vue';
|
import FloatingBtn from '@/components/FloatingBtn.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
FloatingBtn,
|
FloatingBtn,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
config: this.$root.config,
|
config: this.$root.config,
|
||||||
debounce: {
|
debounce: {
|
||||||
saveConfig: null,
|
saveConfig: null,
|
||||||
updateConfig: null
|
updateConfig: null
|
||||||
},
|
},
|
||||||
// Header 菜单项
|
// Header 菜单项
|
||||||
headerMenuItems: [
|
headerMenuItems: [
|
||||||
{
|
{
|
||||||
id: 'home',
|
id: 'home',
|
||||||
label: '主页',
|
label: '主页',
|
||||||
routeName: 'Home'
|
routeName: 'Home'
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'tools',
|
|
||||||
label: '小工具',
|
|
||||||
routeName: 'Tools'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'settings',
|
|
||||||
label: '设置',
|
|
||||||
routeName: 'Settings'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'about',
|
|
||||||
label: '关于',
|
|
||||||
routeName: 'About'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
// 显示下拉菜单
|
|
||||||
showHeaderDropdown: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// Header 默认激活的菜单项
|
|
||||||
headerDefaultActive() {
|
|
||||||
var routeName = this.$route.name;
|
|
||||||
var item = '';
|
|
||||||
|
|
||||||
if (routeName) {
|
|
||||||
item = routeName.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
|
|
||||||
// 路由名称
|
|
||||||
'$route.name': {
|
|
||||||
handler() {
|
|
||||||
// 切换路由时隐藏下拉菜单
|
|
||||||
this.showHeaderDropdown = false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
// 更新储存的设置
|
id: 'tools',
|
||||||
'config.storage': {
|
label: '小工具',
|
||||||
handler(obj) {
|
routeName: 'Tools'
|
||||||
clearTimeout(this.debounce.saveConfig);
|
|
||||||
|
|
||||||
this.debounce.saveConfig = setTimeout(() => {
|
|
||||||
localStorage.setItem('navConfig', JSON.stringify(obj));
|
|
||||||
}, 2000);
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
// 改变字体大小
|
id: 'settings',
|
||||||
'config.storage.fontSize': {
|
label: '设置',
|
||||||
handler(value) {
|
routeName: 'Settings'
|
||||||
clearTimeout(this.debounce.updateConfig);
|
},
|
||||||
|
{
|
||||||
this.debounce.updateConfig = setTimeout(() => {
|
id: 'about',
|
||||||
// 改变字体大小
|
label: '关于',
|
||||||
document.documentElement.style.fontSize = value + 'px';
|
routeName: 'About'
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
var configStr = localStorage.getItem('navConfig');
|
|
||||||
var configObj = {};
|
|
||||||
|
|
||||||
if (configStr != null) {
|
|
||||||
configObj = JSON.parse(configStr);
|
|
||||||
Object.assign(this.config.storage, configObj);
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
// 显示下拉菜单
|
||||||
|
showHeaderDropdown: false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// Header 默认激活的菜单项
|
||||||
|
headerDefaultActive() {
|
||||||
|
var routeName = this.$route.name;
|
||||||
|
var item = '';
|
||||||
|
|
||||||
|
if (routeName) {
|
||||||
|
item = routeName.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
|
||||||
|
// 路由名称
|
||||||
|
'$route.name': {
|
||||||
|
handler() {
|
||||||
|
// 切换路由时隐藏下拉菜单
|
||||||
|
this.showHeaderDropdown = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新储存的设置
|
||||||
|
'config.storage': {
|
||||||
|
handler(obj) {
|
||||||
|
clearTimeout(this.debounce.saveConfig);
|
||||||
|
|
||||||
|
this.debounce.saveConfig = setTimeout(() => {
|
||||||
|
localStorage.setItem('navConfig', JSON.stringify(obj));
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// 改变字体大小
|
||||||
|
'config.storage.fontSize': {
|
||||||
|
handler(value) {
|
||||||
|
clearTimeout(this.debounce.updateConfig);
|
||||||
|
|
||||||
|
this.debounce.updateConfig = setTimeout(() => {
|
||||||
|
// 改变字体大小
|
||||||
|
document.documentElement.style.fontSize = value + 'px';
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
var configStr = localStorage.getItem('navConfig');
|
||||||
|
var configObj = {};
|
||||||
|
|
||||||
|
if (configStr != null) {
|
||||||
|
configObj = JSON.parse(configStr);
|
||||||
|
Object.assign(this.config.storage, configObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.loading-bar {
|
.loading-bar {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0.2rem;
|
||||||
|
|
||||||
|
.bar-content {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1000;
|
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 0;
|
||||||
height: 0.2rem;
|
height: 100%;
|
||||||
|
background-color: @colorPrimary;
|
||||||
|
animation: loadingBar 4s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.bar-content {
|
@keyframes loadingBar {
|
||||||
position: absolute;
|
0% {
|
||||||
top: 0;
|
left: 0;
|
||||||
left: 0;
|
width: 0;
|
||||||
width: 0;
|
|
||||||
height: 100%;
|
|
||||||
background-color: @colorPrimary;
|
|
||||||
animation: loadingBar 4s ease-in-out infinite;
|
|
||||||
}
|
}
|
||||||
|
50% {
|
||||||
@keyframes loadingBar {
|
left: 0;
|
||||||
0% {
|
width: 100%;
|
||||||
left: 0;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: 100%;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
|
left: 100%;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-header {
|
.main-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
height: @headerHeight !important;
|
height: @headerHeight !important;
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
|
|
||||||
@media screen and (min-width: 30rem) {
|
@media screen and (min-width: 30rem) {
|
||||||
.menu .item-dropdown {
|
.menu .item-dropdown {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 30rem) {
|
|
||||||
.logo {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
.item-normal {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-dropdown {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
i {
|
|
||||||
font-size: 1.75em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 30rem) {
|
||||||
.logo {
|
.logo {
|
||||||
flex-shrink: 0;
|
display: none;
|
||||||
margin-right: 1rem;
|
|
||||||
width: 2rem;
|
|
||||||
height: 2rem;
|
|
||||||
background-image: url("./assets/icon/favicon.svg");
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: contain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
flex-grow: 1;
|
.item-normal {
|
||||||
height: 2.5rem;
|
display: none;
|
||||||
border: none !important;
|
}
|
||||||
|
|
||||||
> li {
|
.item-dropdown {
|
||||||
padding: 0 1rem;
|
position: absolute;
|
||||||
height: 100%;
|
right: 0;
|
||||||
line-height: 2.5rem;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
&.is-active {
|
i {
|
||||||
border-bottom-color: transparent;
|
font-size: 1.75em;
|
||||||
color: @colorPrimary !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
padding-left: 0;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
color: @colorPrimary;
|
|
||||||
opacity: 1;
|
|
||||||
cursor: default;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 1rem;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
background-image: url("./assets/icon/favicon.svg");
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 2.5rem;
|
||||||
|
border: none !important;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
padding: 0 1rem;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
color: @colorPrimary !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
padding-left: 0;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: @colorPrimary;
|
||||||
|
opacity: 1;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-container {
|
.main-container {
|
||||||
height: calc(100vh - @headerHeight);
|
height: calc(100vh - @headerHeight);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.header-dropdown {
|
.header-dropdown {
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
z-index: 150;
|
z-index: 150;
|
||||||
top: @headerHeight;
|
top: @headerHeight;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
transition: transform @transitionTime;
|
transition: transform @transitionTime;
|
||||||
|
|
||||||
&.show {
|
&.show {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu .item-dropdown {
|
.menu .item-dropdown {
|
||||||
i {
|
i {
|
||||||
transition: color @transitionTime;
|
transition: color @transitionTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active i {
|
&.active i {
|
||||||
color: @colorPrimary;
|
color: @colorPrimary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,24 +1,30 @@
|
|||||||
// 工具信息列表
|
/**
|
||||||
let navTools = {
|
* @typedef {object} ToolItem
|
||||||
// 分类
|
* @property {string} title 工具标题
|
||||||
|
* @property {string} [desc] 工具简介
|
||||||
|
* @property {string} component 组件名称
|
||||||
|
* @property {string} [update] 更新日期
|
||||||
|
* @property {string} [version] 版本号
|
||||||
|
* @property {boolean} enabled 启用状态
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} ToolCategory
|
||||||
|
* @property {string} title 分类标题
|
||||||
|
* @property {Object.<string, ToolItem>} list 工具列表
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {Object.<string, ToolCategory>} */
|
||||||
|
const navTools = {
|
||||||
calculation: {
|
calculation: {
|
||||||
// 分类标题
|
|
||||||
title: '计算',
|
title: '计算',
|
||||||
// 分类列表
|
|
||||||
list: {
|
list: {
|
||||||
// 工具
|
|
||||||
'download-time': {
|
'download-time': {
|
||||||
// 工具标题
|
|
||||||
title: '下载用时计算',
|
title: '下载用时计算',
|
||||||
// 工具简介
|
|
||||||
desc: '根据设定的文件大小和下载速度简单计算大约下载完成所需的时间。',
|
desc: '根据设定的文件大小和下载速度简单计算大约下载完成所需的时间。',
|
||||||
// 组件名称
|
|
||||||
component: 'CalcDownloadTime',
|
component: 'CalcDownloadTime',
|
||||||
// 更新时间
|
|
||||||
update: '2021-12-06',
|
update: '2021-12-06',
|
||||||
// 版本
|
|
||||||
version: '1',
|
version: '1',
|
||||||
// 启用状态
|
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
'ratio': {
|
'ratio': {
|
||||||
|
@@ -5,8 +5,7 @@ class Utils {
|
|||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 改变网页标题
|
* @description 改变网页标题
|
||||||
*
|
|
||||||
* @param {string} [value] 新的标题
|
* @param {string} [value] 新的标题
|
||||||
*/
|
*/
|
||||||
changeTitle(value) {
|
changeTitle(value) {
|
||||||
@@ -14,8 +13,7 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSONP
|
* @description JSONP
|
||||||
*
|
|
||||||
* @param {object} options 配置选项
|
* @param {object} options 配置选项
|
||||||
*/
|
*/
|
||||||
jsonp(options) {
|
jsonp(options) {
|
||||||
@@ -40,11 +38,9 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 以文本方式读取文件(异步)
|
* @description 以文本方式读取文件(异步)
|
||||||
*
|
|
||||||
* @param {Event} ev 输入框 change 事件对象
|
* @param {Event} ev 输入框 change 事件对象
|
||||||
* @param {boolean} resetValue 是否自动重置输入框 value 属性
|
* @param {boolean} resetValue 是否自动重置输入框 value 属性
|
||||||
*
|
|
||||||
* @returns {Promise<string[]>} `{ name: 文件名, content: 文件内容 }`
|
* @returns {Promise<string[]>} `{ name: 文件名, content: 文件内容 }`
|
||||||
*/
|
*/
|
||||||
readFileAsText(ev, resetValue) {
|
readFileAsText(ev, resetValue) {
|
||||||
|
@@ -1,214 +1,214 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="floatingBtn" class="floating-btn">
|
<div ref="floatingBtn" class="floating-btn">
|
||||||
<div :class="['btns-inner', { show: showInner }]">
|
<div :class="['btns-inner', { show: showInner }]">
|
||||||
<button class="btn" type="button" title="折叠侧边菜单" @click="toggleSideCollapse()">
|
<button class="btn" type="button" title="折叠侧边菜单" @click="toggleSideCollapse()">
|
||||||
<i class="el-icon-menu" aria-hidden="true"></i>
|
<i class="el-icon-menu" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn" type="button" title="刷新" @click="refreshPage()">
|
<button class="btn" type="button" title="刷新" @click="refreshPage()">
|
||||||
<i class="el-icon-refresh-right" aria-hidden="true"></i>
|
<i class="el-icon-refresh-right" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn" type="button" title="返回主页" @click="backToHome()">
|
<button class="btn" type="button" title="返回主页" @click="backToHome()">
|
||||||
<i class="el-icon-s-home" aria-hidden="true"></i>
|
<i class="el-icon-s-home" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
<div class="btns-outer">
|
|
||||||
<button class="btn" type="button" title="菜单">
|
|
||||||
<i class="fa fa-bars" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="btns-outer">
|
||||||
|
<button class="btn" type="button" title="菜单">
|
||||||
|
<i class="fa fa-bars" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'FloatingBtn',
|
name: 'FloatingBtn',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
config: this.$root.config.storage,
|
config: this.$root.config.storage,
|
||||||
showInner: false
|
showInner: false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.initAnimation();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置动画
|
||||||
|
*/
|
||||||
|
initAnimation() {
|
||||||
|
var vm = this;
|
||||||
|
var el = vm.$refs['floatingBtn'];
|
||||||
|
var btns = el.querySelectorAll('.btn');
|
||||||
|
var className = 'animate';
|
||||||
|
|
||||||
|
btns.forEach((elem) => {
|
||||||
|
elem.addEventListener('click', function () {
|
||||||
|
this.classList.remove(className);
|
||||||
|
setTimeout(() => {
|
||||||
|
this.classList.add(className);
|
||||||
|
vm.toggleInnerBtns();
|
||||||
|
}, 20);
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
mounted () {
|
|
||||||
this.initAnimation();
|
/**
|
||||||
|
* 切换按钮显示
|
||||||
|
*/
|
||||||
|
toggleInnerBtns() {
|
||||||
|
this.showInner = !this.showInner;
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置动画
|
* 返回主页
|
||||||
*/
|
*/
|
||||||
initAnimation() {
|
backToHome() {
|
||||||
var vm = this;
|
var routeName = 'Home';
|
||||||
var el = vm.$refs['floatingBtn'];
|
|
||||||
var btns = el.querySelectorAll('.btn');
|
|
||||||
var className = 'animate';
|
|
||||||
|
|
||||||
btns.forEach((elem) => {
|
|
||||||
elem.addEventListener('click', function () {
|
|
||||||
this.classList.remove(className);
|
|
||||||
setTimeout(() => {
|
|
||||||
this.classList.add(className);
|
|
||||||
vm.toggleInnerBtns();
|
|
||||||
}, 20);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换按钮显示
|
|
||||||
*/
|
|
||||||
toggleInnerBtns() {
|
|
||||||
this.showInner = !this.showInner;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回主页
|
|
||||||
*/
|
|
||||||
backToHome() {
|
|
||||||
var routeName = 'Home';
|
|
||||||
|
|
||||||
if (this.$route.name != routeName) {
|
|
||||||
this.$router.push({
|
|
||||||
name: routeName
|
|
||||||
}).then(() => {
|
|
||||||
window.location.reload();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.$message({
|
|
||||||
duration: 2000,
|
|
||||||
message: '已经在主页啦~',
|
|
||||||
type: 'warning'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 刷新
|
|
||||||
*/
|
|
||||||
refreshPage() {
|
|
||||||
window.location.reload();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换侧边菜单折叠状态
|
|
||||||
*/
|
|
||||||
toggleSideCollapse() {
|
|
||||||
var cfg = this.config;
|
|
||||||
cfg.sideMenuCollapse = !cfg.sideMenuCollapse;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
if (this.$route.name != routeName) {
|
||||||
|
this.$router.push({
|
||||||
|
name: routeName
|
||||||
|
}).then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$message({
|
||||||
|
duration: 2000,
|
||||||
|
message: '已经在主页啦~',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新
|
||||||
|
*/
|
||||||
|
refreshPage() {
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换侧边菜单折叠状态
|
||||||
|
*/
|
||||||
|
toggleSideCollapse() {
|
||||||
|
var cfg = this.config;
|
||||||
|
cfg.sideMenuCollapse = !cfg.sideMenuCollapse;
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.floating-btn {
|
.floating-btn {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 5000;
|
z-index: 5000;
|
||||||
right: 2rem;
|
right: 2rem;
|
||||||
bottom: 2rem;
|
bottom: 2rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.btns-inner.show .btn {
|
.btns-inner.show .btn {
|
||||||
width: 2.6rem;
|
width: 2.6rem;
|
||||||
height: 2.6rem;
|
height: 2.6rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 400px) {
|
@media screen and (max-width: 400px) {
|
||||||
right: 1.5rem;
|
right: 1.5rem;
|
||||||
bottom: 1.5rem;
|
bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btns-inner {
|
.btns-inner {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
background-color: @colorSecondary;
|
background-color: @colorSecondary;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
transition: all @transitionTime;
|
transition: all @transitionTime;
|
||||||
|
|
||||||
&:not(:first-child) {
|
&:not(:first-child) {
|
||||||
margin-top: 0.75rem;
|
margin-top: 0.75rem;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btns-outer {
|
.btns-outer {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
width: 3.2rem;
|
width: 3.2rem;
|
||||||
height: 3.2rem;
|
height: 3.2rem;
|
||||||
background-color: @colorPrimary;
|
background-color: @colorPrimary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
box-shadow: 0 0.15rem 0.15rem 0 rgba(0, 0, 0, 0.14),
|
box-shadow: 0 0.15rem 0.15rem 0 rgba(0, 0, 0, 0.14),
|
||||||
0 0.2rem 0.1rem -0.15rem rgba(0, 0, 0, 0.12),
|
0 0.2rem 0.1rem -0.15rem rgba(0, 0, 0, 0.12),
|
||||||
0 0.1rem 0.3rem 0 rgba(0, 0, 0, 0.20);
|
0 0.1rem 0.3rem 0 rgba(0, 0, 0, 0.20);
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #FFF;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&::before, &::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
font-size: 1rem;
|
background-color: #FFF;
|
||||||
color: #FFF;
|
opacity: 0;
|
||||||
overflow: hidden;
|
transition: opacity @transitionTime;
|
||||||
cursor: pointer;
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
&::before, &::after {
|
&:hover::before {
|
||||||
content: "";
|
opacity: 0.1;
|
||||||
display: block;
|
}
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: #FFF;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity @transitionTime;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover::before {
|
&.animate::after {
|
||||||
opacity: 0.1;
|
animation: floatingBtnClick calc(@transitionTime * 2) linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.animate::after {
|
|
||||||
animation: floatingBtnClick calc(@transitionTime * 2) linear;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes floatingBtnClick {
|
@keyframes floatingBtnClick {
|
||||||
0% {
|
0% {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
25% {
|
25% {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
75% {
|
75% {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,67 +1,67 @@
|
|||||||
<template>
|
<template>
|
||||||
<i class="icon-element bg-center-contain" :style="iconStyle"></i>
|
<i class="icon-element bg-center-contain" :style="iconStyle"></i>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'IconElement',
|
name: 'IconElement',
|
||||||
props: {
|
props: {
|
||||||
// 来源(inner、outer)
|
// 来源(inner、outer)
|
||||||
from: {
|
from: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'inner'
|
default: 'inner'
|
||||||
},
|
|
||||||
// 路径
|
|
||||||
// 若为 inner,自动添加 @/assets/icon/
|
|
||||||
path: {
|
|
||||||
type: String,
|
|
||||||
default: 'unknown.svg'
|
|
||||||
},
|
|
||||||
// 尺寸
|
|
||||||
size: {
|
|
||||||
type: String,
|
|
||||||
default: '1em'
|
|
||||||
},
|
|
||||||
// 显示图标
|
|
||||||
showIcon: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
// 路径
|
||||||
// 图标样式
|
// 若为 inner,自动添加 @/assets/icon/
|
||||||
iconStyle() {
|
path: {
|
||||||
var style = {
|
type: String,
|
||||||
width: this.size,
|
default: 'unknown.svg'
|
||||||
height: this.size
|
},
|
||||||
};
|
// 尺寸
|
||||||
var iconPath = '';
|
size: {
|
||||||
|
type: String,
|
||||||
// 不显示图标内容
|
default: '1em'
|
||||||
if (!this.showIcon) {
|
},
|
||||||
return style;
|
// 显示图标
|
||||||
}
|
showIcon: {
|
||||||
|
type: Boolean,
|
||||||
if (this.from === 'inner') {
|
default: true
|
||||||
// 内部
|
|
||||||
iconPath = require(`@/assets/icon/${this.path}`);
|
|
||||||
} else if (this.from === 'outer') {
|
|
||||||
// 外部
|
|
||||||
iconPath = this.path;
|
|
||||||
}
|
|
||||||
|
|
||||||
style.backgroundImage = `url('${iconPath}')`;
|
|
||||||
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 图标样式
|
||||||
|
iconStyle() {
|
||||||
|
var style = {
|
||||||
|
width: this.size,
|
||||||
|
height: this.size
|
||||||
|
};
|
||||||
|
var iconPath = '';
|
||||||
|
|
||||||
|
// 不显示图标内容
|
||||||
|
if (!this.showIcon) {
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.from === 'inner') {
|
||||||
|
// 内部
|
||||||
|
iconPath = require(`@/assets/icon/${this.path}`);
|
||||||
|
} else if (this.from === 'outer') {
|
||||||
|
// 外部
|
||||||
|
iconPath = this.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
style.backgroundImage = `url('${iconPath}')`;
|
||||||
|
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.icon-element {
|
.icon-element {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,164 +1,190 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tool-page">
|
<div class="tool-page">
|
||||||
|
|
||||||
<div class="info">
|
|
||||||
<div class="title">配置选项 & 结果</div>
|
|
||||||
<div class="content">
|
|
||||||
<el-form label-width="6rem">
|
|
||||||
<!-- 字符串长度 -->
|
|
||||||
<el-form-item label="字符串长度">
|
|
||||||
<el-input v-model.number="info.strLength" type="number" min="1" max="1024"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 字符串格式 -->
|
|
||||||
<el-form-item label="字符串格式">
|
|
||||||
<el-checkbox v-model="info.option.hasNum"
|
|
||||||
name="option" label="hasNum"
|
|
||||||
>数字</el-checkbox>
|
|
||||||
<el-checkbox v-model="info.option.hasChar"
|
|
||||||
name="option" label="hasChar"
|
|
||||||
>字母</el-checkbox>
|
|
||||||
<el-checkbox v-model="info.option.hasSymbol"
|
|
||||||
name="option" label="hasSymbol"
|
|
||||||
>其他符号</el-checkbox>
|
|
||||||
<el-checkbox v-model="info.option.caseSensitive"
|
|
||||||
name="option" label="caseSensitive"
|
|
||||||
>大小写</el-checkbox>
|
|
||||||
<el-checkbox v-model="info.option.lowerCase"
|
|
||||||
name="option" label="lowerCase"
|
|
||||||
>全小写(需关闭“大小写”)</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 生成结果 -->
|
|
||||||
<el-form-item label="生成结果">
|
|
||||||
<el-input v-model="info.result" type="text" readonly></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="action">
|
|
||||||
<div class="title">操作</div>
|
|
||||||
<div class="content">
|
|
||||||
<el-button type="primary" @click="btnGenerate()">生成</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="reference">
|
|
||||||
<div class="title">参考资料</div>
|
|
||||||
<div class="content">
|
|
||||||
<el-link href="https://www.cnblogs.com/hankuksui/p/9892729.html" target="_blank" type="primary">博客园 - hankuksui</el-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="info">
|
||||||
|
<div class="title">配置选项 & 结果</div>
|
||||||
|
<div class="content">
|
||||||
|
<el-form label-width="6rem">
|
||||||
|
<!-- 字符串长度 -->
|
||||||
|
<el-form-item label="字符串长度">
|
||||||
|
<el-input
|
||||||
|
v-model.number="info.strLength"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
max="1024"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 字符串格式 -->
|
||||||
|
<el-form-item label="字符串格式">
|
||||||
|
<el-checkbox
|
||||||
|
v-model="info.option.hasNum"
|
||||||
|
name="option"
|
||||||
|
label="hasNum"
|
||||||
|
>数字</el-checkbox>
|
||||||
|
<el-checkbox
|
||||||
|
v-model="info.option.hasChar"
|
||||||
|
name="option"
|
||||||
|
label="hasChar"
|
||||||
|
>字母</el-checkbox>
|
||||||
|
<el-checkbox
|
||||||
|
v-model="info.option.hasSymbol"
|
||||||
|
name="option"
|
||||||
|
label="hasSymbol"
|
||||||
|
>其他符号</el-checkbox>
|
||||||
|
<el-checkbox
|
||||||
|
v-model="info.option.caseSensitive"
|
||||||
|
name="option"
|
||||||
|
label="caseSensitive"
|
||||||
|
>大小写</el-checkbox>
|
||||||
|
<el-checkbox
|
||||||
|
v-model="info.option.lowerCase"
|
||||||
|
name="option"
|
||||||
|
label="lowerCase"
|
||||||
|
>全小写(需关闭“大小写”)</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 生成结果 -->
|
||||||
|
<el-form-item label="生成结果">
|
||||||
|
<el-input
|
||||||
|
v-model="info.result"
|
||||||
|
type="text"
|
||||||
|
readonly
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="action">
|
||||||
|
<div class="title">操作</div>
|
||||||
|
<div class="content">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="btnGenerate()"
|
||||||
|
>生成</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="reference">
|
||||||
|
<div class="title">参考资料</div>
|
||||||
|
<div class="content">
|
||||||
|
<el-link
|
||||||
|
href="https://www.cnblogs.com/hankuksui/p/9892729.html"
|
||||||
|
target="_blank"
|
||||||
|
type="primary"
|
||||||
|
>博客园 - hankuksui</el-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'GenRandomStr',
|
name: 'GenRandomStr',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
info: {
|
info: {
|
||||||
strLength: 8,
|
strLength: 8,
|
||||||
option: {
|
option: {
|
||||||
caseSensitive: true,
|
caseSensitive: true,
|
||||||
hasNum: true,
|
hasNum: true,
|
||||||
hasChar: true,
|
hasChar: true,
|
||||||
hasSymbol: false,
|
hasSymbol: false,
|
||||||
lowerCase: false
|
lowerCase: false
|
||||||
},
|
|
||||||
result: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成
|
|
||||||
*/
|
|
||||||
btnGenerate() {
|
|
||||||
var len = this.info.strLength;
|
|
||||||
var op = this.info.option;
|
|
||||||
var r = this.genRandomStr(len, op.hasNum, op.hasChar, op.hasSymbol, op.caseSensitive, op.lowerCase);
|
|
||||||
|
|
||||||
this.info.result = r;
|
|
||||||
},
|
},
|
||||||
|
result: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机字符串
|
* 生成
|
||||||
*
|
*/
|
||||||
* @param {number} strLength 长度
|
btnGenerate() {
|
||||||
* @param {boolean} hasNum 是否包含数字
|
var len = this.info.strLength;
|
||||||
* @param {boolean} hasChar 是否包含字母
|
var op = this.info.option;
|
||||||
* @param {boolean} hasSymbol 是否包含其他符号
|
var r = this.genRandomStr(len, op.hasNum, op.hasChar, op.hasSymbol, op.caseSensitive, op.lowerCase);
|
||||||
* @param {boolean} caseSensitive 是否包含大小写
|
|
||||||
* @param {boolean} lowerCase 是否全小写(当 caseSensitive 为 false 时起作用)
|
|
||||||
*
|
|
||||||
* @returns {string} 生成的字符串
|
|
||||||
*/
|
|
||||||
genRandomStr(strLength, hasNum, hasChar, hasSymbol, caseSensitive, lowerCase) {
|
|
||||||
var result = '请选中数字、字母或其他符号的其中一项!';
|
|
||||||
|
|
||||||
if (hasNum === false && hasChar === false && hasSymbol === false) {
|
this.info.result = r;
|
||||||
return result;
|
},
|
||||||
}
|
|
||||||
|
|
||||||
result = '';
|
/**
|
||||||
|
* 生成随机字符串
|
||||||
|
*
|
||||||
|
* @param {number} strLength 长度
|
||||||
|
* @param {boolean} hasNum 是否包含数字
|
||||||
|
* @param {boolean} hasChar 是否包含字母
|
||||||
|
* @param {boolean} hasSymbol 是否包含其他符号
|
||||||
|
* @param {boolean} caseSensitive 是否包含大小写
|
||||||
|
* @param {boolean} lowerCase 是否全小写(当 caseSensitive 为 false 时起作用)
|
||||||
|
*
|
||||||
|
* @returns {string} 生成的字符串
|
||||||
|
*/
|
||||||
|
genRandomStr(strLength, hasNum, hasChar, hasSymbol, caseSensitive, lowerCase) {
|
||||||
|
var result = '请选中数字、字母或其他符号的其中一项!';
|
||||||
|
|
||||||
for (var i = strLength; i > 0; i--) {
|
if (hasNum === false && hasChar === false && hasSymbol === false) {
|
||||||
let num = Math.floor((Math.random() * 94) + 33);
|
return result;
|
||||||
let flag = ((
|
}
|
||||||
(hasNum === false) && ((num >= 48) && (num <= 57))
|
|
||||||
) || (
|
|
||||||
(hasChar === false) && ((
|
|
||||||
(num >= 65) && (num <= 90)
|
|
||||||
) || (
|
|
||||||
(num >= 97) && (num <= 122)
|
|
||||||
))
|
|
||||||
) || (
|
|
||||||
(hasSymbol === false) && ((
|
|
||||||
(num >= 33) && (num <= 47)
|
|
||||||
) || (
|
|
||||||
(num >= 58) && (num <= 64)
|
|
||||||
) || (
|
|
||||||
(num >= 91) && (num <= 96)
|
|
||||||
) || (
|
|
||||||
(num >= 123) && (num <= 127)
|
|
||||||
)
|
|
||||||
)));
|
|
||||||
|
|
||||||
if (flag) {
|
result = '';
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
for (var i = strLength; i > 0; i--) {
|
||||||
* | CharCode | 符号 |
|
let num = Math.floor((Math.random() * 94) + 33);
|
||||||
* | :--------- | :----- |
|
let flag = ((
|
||||||
* | 033 -> 047 | ! -> / |
|
(hasNum === false) && ((num >= 48) && (num <= 57))
|
||||||
* | 048 -> 057 | 0 -> 9 |
|
) || (
|
||||||
* | 058 -> 064 | : -> @ |
|
(hasChar === false) && ((
|
||||||
* | 065 -> 090 | A -> Z |
|
(num >= 65) && (num <= 90)
|
||||||
* | 091 -> 096 | [ -> ` |
|
) || (
|
||||||
* | 097 -> 122 | a -> z |
|
(num >= 97) && (num <= 122)
|
||||||
* | 123 -> 127 | { -> |
|
))
|
||||||
*/
|
) || (
|
||||||
|
(hasSymbol === false) && ((
|
||||||
|
(num >= 33) && (num <= 47)
|
||||||
|
) || (
|
||||||
|
(num >= 58) && (num <= 64)
|
||||||
|
) || (
|
||||||
|
(num >= 91) && (num <= 96)
|
||||||
|
) || (
|
||||||
|
(num >= 123) && (num <= 127)
|
||||||
|
)
|
||||||
|
)));
|
||||||
|
|
||||||
result += String.fromCharCode(num);
|
if (flag) {
|
||||||
}
|
i++;
|
||||||
|
continue;
|
||||||
if (caseSensitive === false) {
|
|
||||||
result = (lowerCase ? result.toLocaleLowerCase() : result.toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
/**
|
||||||
|
* | CharCode | 符号 |
|
||||||
|
* | :--------- | :----- |
|
||||||
|
* | 033 -> 047 | ! -> / |
|
||||||
|
* | 048 -> 057 | 0 -> 9 |
|
||||||
|
* | 058 -> 064 | : -> @ |
|
||||||
|
* | 065 -> 090 | A -> Z |
|
||||||
|
* | 091 -> 096 | [ -> ` |
|
||||||
|
* | 097 -> 122 | a -> z |
|
||||||
|
* | 123 -> 127 | { -> |
|
||||||
|
*/
|
||||||
|
|
||||||
|
result += String.fromCharCode(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caseSensitive === false) {
|
||||||
|
result = (lowerCase ? result.toLocaleLowerCase() : result.toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.content {
|
.content {
|
||||||
max-width: 30rem;
|
max-width: 30rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,93 +1,93 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tool-page">
|
<div class="tool-page">
|
||||||
|
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="title">信息</div>
|
<div class="title">信息</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="link">
|
<div class="link">
|
||||||
<span class="label">目标链接:</span>
|
<span class="label">目标链接:</span>
|
||||||
<el-input v-model="info.link" type="text" placeholder="需要包含协议(例如 https://)" />
|
<el-input v-model="info.link" type="text" placeholder="需要包含协议(例如 https://)" />
|
||||||
</div>
|
|
||||||
<div class="size">
|
|
||||||
<span class="label">窗口大小:</span>
|
|
||||||
<el-input v-model="info.size.width" type="number" min="1" placeholder="宽度(默认 400)" />
|
|
||||||
<el-input v-model="info.size.height" type="number" min="1" placeholder="高度(默认 300)" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="size">
|
||||||
<div class="action">
|
<span class="label">窗口大小:</span>
|
||||||
<div class="title">操作</div>
|
<el-input v-model="info.size.width" type="number" min="1" placeholder="宽度(默认 400)" />
|
||||||
<div class="content">
|
<el-input v-model="info.size.height" type="number" min="1" placeholder="高度(默认 300)" />
|
||||||
<el-button type="primary" @click="btnOpen()">打开</el-button>
|
|
||||||
<el-button type="danger" @click="btnClear()">清空</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="action">
|
||||||
|
<div class="title">操作</div>
|
||||||
|
<div class="content">
|
||||||
|
<el-button type="primary" @click="btnOpen()">打开</el-button>
|
||||||
|
<el-button type="danger" @click="btnClear()">清空</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'OtherNewWindow',
|
name: 'OtherNewWindow',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
info: {
|
info: {
|
||||||
link: '',
|
link: '',
|
||||||
size: {
|
size: {
|
||||||
width: '',
|
width: '',
|
||||||
height: ''
|
height: ''
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
// 打开
|
||||||
|
btnOpen() {
|
||||||
|
var link = this.info.link || 'https://github.com/Frost-ZX';
|
||||||
|
var width = this.info.size.width || '400';
|
||||||
|
var height = this.info.size.height || '300';
|
||||||
|
var features = `height=${height}, width=${width}, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=yes, status=yes`;
|
||||||
|
|
||||||
|
window.open(link, '_blank', features);
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
|
|
||||||
// 打开
|
// 清空
|
||||||
btnOpen() {
|
btnClear() {
|
||||||
var link = this.info.link || 'https://github.com/Frost-ZX';
|
// 重置 info
|
||||||
var width = this.info.size.width || '400';
|
this.info = {
|
||||||
var height = this.info.size.height || '300';
|
link: '',
|
||||||
var features = `height=${height}, width=${width}, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=yes, status=yes`;
|
size: {
|
||||||
|
width: '',
|
||||||
window.open(link, '_blank', features);
|
height: ''
|
||||||
},
|
|
||||||
|
|
||||||
// 清空
|
|
||||||
btnClear() {
|
|
||||||
// 重置 info
|
|
||||||
this.info = {
|
|
||||||
link: '',
|
|
||||||
size: {
|
|
||||||
width: '',
|
|
||||||
height: ''
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.content {
|
.content {
|
||||||
max-width: 40rem;
|
max-width: 40rem;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 5rem;
|
width: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input {
|
.el-input {
|
||||||
margin: 0 0.5rem;
|
margin: 0 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,34 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tool-page">
|
<div class="tool-page">
|
||||||
|
|
||||||
<!-- 输入 -->
|
|
||||||
<div class="input">
|
|
||||||
<div class="title">代码</div>
|
|
||||||
<div class="text">
|
|
||||||
<textarea ref="jsInput" placeholder="代码"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 操作 -->
|
|
||||||
<div class="action">
|
|
||||||
<div class="title">操作</div>
|
|
||||||
<div class="btns">
|
|
||||||
<el-button type="primary" @click="btnRun()">执行</el-button>
|
|
||||||
<el-button type="danger" @click="btnClear()">清空</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 输出 -->
|
|
||||||
<div class="output">
|
|
||||||
<div class="title">输出</div>
|
|
||||||
<div class="text">
|
|
||||||
<p v-for="line in output.lines" :key="line.id"
|
|
||||||
:class="['line', line.type]"
|
|
||||||
>{{ line.message }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<!-- 输入 -->
|
||||||
|
<div class="input">
|
||||||
|
<div class="title">代码</div>
|
||||||
|
<div class="text">
|
||||||
|
<textarea ref="jsInput" placeholder="代码"></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 操作 -->
|
||||||
|
<div class="action">
|
||||||
|
<div class="title">操作</div>
|
||||||
|
<div class="btns">
|
||||||
|
<el-button type="primary" @click="btnRun()">执行</el-button>
|
||||||
|
<el-button type="danger" @click="btnClear()">清空</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 输出 -->
|
||||||
|
<div class="output">
|
||||||
|
<div class="title">输出</div>
|
||||||
|
<div class="text">
|
||||||
|
<p
|
||||||
|
v-for="line in output.lines"
|
||||||
|
:key="line.id"
|
||||||
|
:class="['line', line.type]"
|
||||||
|
>{{ line.message }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -37,144 +39,144 @@ import 'codemirror/mode/javascript/javascript';
|
|||||||
import 'codemirror/lib/codemirror.css';
|
import 'codemirror/lib/codemirror.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'OtherRunJS',
|
name: 'OtherRunJS',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
input: {
|
input: {
|
||||||
editor: null,
|
editor: null,
|
||||||
value: ''
|
value: ''
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
id: 0,
|
id: 0,
|
||||||
lines: []
|
lines: []
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
init() {
|
||||||
|
var jsInput = this.$refs['jsInput'];
|
||||||
|
var datas = this.input;
|
||||||
|
|
||||||
|
datas.editor = CodeMirror.fromTextArea(jsInput, {
|
||||||
|
indentWithTabs: false,
|
||||||
|
indentUnit: 4,
|
||||||
|
lineNumbers: true,
|
||||||
|
mode: 'javascript',
|
||||||
|
theme: 'default'
|
||||||
|
});
|
||||||
|
|
||||||
|
datas.editor.setOption('extraKeys', {
|
||||||
|
// Tab 转空格
|
||||||
|
Tab: function(cm) {
|
||||||
|
var spaces = Array(cm.getOption('indentUnit') + 1).join(' ');
|
||||||
|
cm.replaceSelection(spaces);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
datas.editor.on('change', function (instance) {
|
||||||
|
// 同步 value
|
||||||
|
datas.value = instance.doc.getValue();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
mounted () {
|
|
||||||
this.init();
|
// 运行
|
||||||
|
btnRun() {
|
||||||
|
var output = this.output;
|
||||||
|
|
||||||
|
output.lines = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
window.eval(this.input.value);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
|
||||||
|
let time = new Date();
|
||||||
|
|
||||||
|
output.id += 1;
|
||||||
|
output.lines.push({
|
||||||
|
id: output.id + '_' + time.getTime(),
|
||||||
|
message: err.message,
|
||||||
|
stack: err.stack,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
|
|
||||||
// 初始化
|
// 清空
|
||||||
init() {
|
btnClear() {
|
||||||
var jsInput = this.$refs['jsInput'];
|
this.$confirm('确定要清空输入和输出的内容吗?', '', {
|
||||||
var datas = this.input;
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
|
||||||
datas.editor = CodeMirror.fromTextArea(jsInput, {
|
this.input.editor.doc.setValue('');
|
||||||
indentWithTabs: false,
|
this.output.lines = [];
|
||||||
indentUnit: 4,
|
this.$message({
|
||||||
lineNumbers: true,
|
message: '已清除',
|
||||||
mode: 'javascript',
|
type: 'success'
|
||||||
theme: 'default'
|
});
|
||||||
});
|
|
||||||
|
|
||||||
datas.editor.setOption('extraKeys', {
|
}).catch(() => {
|
||||||
// Tab 转空格
|
|
||||||
Tab: function(cm) {
|
|
||||||
var spaces = Array(cm.getOption('indentUnit') + 1).join(' ');
|
|
||||||
cm.replaceSelection(spaces);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
datas.editor.on('change', function (instance) {
|
this.$message({
|
||||||
// 同步 value
|
message: '取消清除',
|
||||||
datas.value = instance.doc.getValue();
|
type: 'info'
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
// 运行
|
});
|
||||||
btnRun() {
|
}
|
||||||
var output = this.output;
|
|
||||||
|
|
||||||
output.lines = [];
|
},
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
window.eval(this.input.value);
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
|
|
||||||
let time = new Date();
|
|
||||||
|
|
||||||
output.id += 1;
|
|
||||||
output.lines.push({
|
|
||||||
id: output.id + '_' + time.getTime(),
|
|
||||||
message: err.message,
|
|
||||||
stack: err.stack,
|
|
||||||
type: 'error'
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 清空
|
|
||||||
btnClear() {
|
|
||||||
this.$confirm('确定要清空输入和输出的内容吗?', '', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning'
|
|
||||||
}).then(() => {
|
|
||||||
|
|
||||||
this.input.editor.doc.setValue('');
|
|
||||||
this.output.lines = [];
|
|
||||||
this.$message({
|
|
||||||
message: '已清除',
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
|
|
||||||
}).catch(() => {
|
|
||||||
|
|
||||||
this.$message({
|
|
||||||
message: '取消清除',
|
|
||||||
type: 'info'
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.tool-page {
|
.tool-page {
|
||||||
@lineHeight: 1.25rem;
|
@lineHeight: 1.25rem;
|
||||||
|
|
||||||
padding-bottom: 5rem;
|
padding-bottom: 5rem;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
.text {
|
.text {
|
||||||
line-height: @lineHeight;
|
line-height: @lineHeight;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
/deep/ .CodeMirror {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(@lineHeight * 20 + 0.5rem);
|
||||||
|
box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.1);
|
||||||
|
line-height: @lineHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.output {
|
||||||
|
.text {
|
||||||
|
padding: 1rem;
|
||||||
|
height: calc(@lineHeight * 10);
|
||||||
|
border: 0.1rem solid #EEE;
|
||||||
|
border-radius: 0.32rem;
|
||||||
|
overflow: auto;
|
||||||
|
user-select: text;
|
||||||
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.line {
|
||||||
/deep/ .CodeMirror {
|
&.error {
|
||||||
width: 100%;
|
color: @colorRed;
|
||||||
height: calc(@lineHeight * 20 + 0.5rem);
|
}
|
||||||
box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.1);
|
|
||||||
line-height: @lineHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.output {
|
|
||||||
.text {
|
|
||||||
padding: 1rem;
|
|
||||||
height: calc(@lineHeight * 10);
|
|
||||||
border: 0.1rem solid #EEE;
|
|
||||||
border-radius: 0.32rem;
|
|
||||||
overflow: auto;
|
|
||||||
user-select: text;
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line {
|
|
||||||
&.error {
|
|
||||||
color: @colorRed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,95 +1,95 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="about">
|
<el-container class="about">
|
||||||
<div class="wrapper shadow-2">
|
<div class="wrapper shadow-2">
|
||||||
|
|
||||||
<div class="text">
|
|
||||||
<div class="title">简介</div>
|
|
||||||
<div class="content">
|
|
||||||
<p>一个多功能的网址导航,绿色无广告。</p>
|
|
||||||
<p>右键点击(PC端)或长按(移动端)链接项可查看链接详情。</p>
|
|
||||||
<p>当前版本:2.0.0</p>
|
|
||||||
<p>链接版本:{{ navLinks.version }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text">
|
|
||||||
<div class="title">开发人员</div>
|
|
||||||
<div class="content">
|
|
||||||
<p>Frost-ZX</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text">
|
|
||||||
<div class="title">注意事项</div>
|
|
||||||
<div class="content">
|
|
||||||
<p>部分链接由于不能及时更新,可能已过期(不存在、指向了错误的网站等),访问时请注意。</p>
|
|
||||||
<p>若您在使用时发现相关情况,欢迎进行反馈。</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text">
|
|
||||||
<div class="title">GitHub</div>
|
|
||||||
<div class="content">
|
|
||||||
<p>
|
|
||||||
<el-link :href="info.github" target="_blank" type="primary">{{ info.github }}</el-link>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="text">
|
||||||
|
<div class="title">简介</div>
|
||||||
|
<div class="content">
|
||||||
|
<p>一个多功能的网址导航,绿色无广告。</p>
|
||||||
|
<p>右键点击(PC端)或长按(移动端)链接项可查看链接详情。</p>
|
||||||
|
<p>当前版本:2.0.0</p>
|
||||||
|
<p>链接版本:{{ navLinks.version }}</p>
|
||||||
</div>
|
</div>
|
||||||
</el-container>
|
</div>
|
||||||
|
|
||||||
|
<div class="text">
|
||||||
|
<div class="title">开发人员</div>
|
||||||
|
<div class="content">
|
||||||
|
<p>Frost-ZX</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text">
|
||||||
|
<div class="title">注意事项</div>
|
||||||
|
<div class="content">
|
||||||
|
<p>部分链接由于不能及时更新,可能已过期(不存在、指向了错误的网站等),访问时请注意。</p>
|
||||||
|
<p>若您在使用时发现相关情况,欢迎进行反馈。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text">
|
||||||
|
<div class="title">GitHub</div>
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
<el-link :href="info.github" target="_blank" type="primary">{{ info.github }}</el-link>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'AboutView',
|
name: 'AboutView',
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
next(vm => {
|
next(vm => {
|
||||||
vm.utils.changeTitle('关于');
|
vm.utils.changeTitle('关于');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
navLinks: this.$root.navLinks,
|
navLinks: this.$root.navLinks,
|
||||||
utils: this.$root.utils,
|
utils: this.$root.utils,
|
||||||
info: {
|
info: {
|
||||||
github: 'https://github.com/Frost-ZX/frost-navigation'
|
github: 'https://github.com/Frost-ZX/frost-navigation'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.about {
|
.about {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
background-color: @colorWhite;
|
background-color: @colorWhite;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
padding: 1.5rem 2rem;
|
padding: 1.5rem 2rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 50rem;
|
max-width: 50rem;
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
line-height: 2.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: @textPrimary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.content {
|
||||||
padding: 0.5rem 0;
|
line-height: 1.8rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
.title {
|
color: @textSecondary;
|
||||||
line-height: 2.5rem;
|
|
||||||
font-size: 1rem;
|
|
||||||
color: @textPrimary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
line-height: 1.8rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
color: @textSecondary;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,141 +1,141 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="settings">
|
<el-container class="settings">
|
||||||
<div class="wrapper shadow-2">
|
<div class="wrapper shadow-2">
|
||||||
|
|
||||||
<el-form label-position="left" label-width="12rem">
|
<el-form label-position="left" label-width="12rem">
|
||||||
|
|
||||||
<el-form-item label="字体大小" class="set-font">
|
<el-form-item label="字体大小" class="set-font">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="config.fontSize"
|
v-model="config.fontSize"
|
||||||
:min="12"
|
:min="12"
|
||||||
:max="32"
|
:max="32"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
label="字体大小"
|
label="字体大小"
|
||||||
size="small"
|
size="small"
|
||||||
></el-input-number>
|
></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="显示网站标题">
|
<el-form-item label="显示网站标题">
|
||||||
<el-switch v-model="config.showSiteTitle"></el-switch>
|
<el-switch v-model="config.showSiteTitle"></el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="折叠主页侧边菜单">
|
<el-form-item label="折叠主页侧边菜单">
|
||||||
<el-switch v-model="config.sideMenuCollapse"></el-switch>
|
<el-switch v-model="config.sideMenuCollapse"></el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="获取搜索引擎关键词建议">
|
<el-form-item label="获取搜索引擎关键词建议">
|
||||||
<el-switch v-model="config.searchSuggestion"></el-switch>
|
<el-switch v-model="config.searchSuggestion"></el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="清除数据">
|
<el-form-item label="清除数据">
|
||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
size="medium"
|
size="medium"
|
||||||
@click="resetDatas('settings')"
|
@click="resetDatas('settings')"
|
||||||
>清除设置</el-button>
|
>清除设置</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
size="medium"
|
size="medium"
|
||||||
@click="resetDatas('cache')"
|
@click="resetDatas('cache')"
|
||||||
>清除缓存</el-button>
|
>清除缓存</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'SettingsView',
|
name: 'SettingsView',
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
next(vm => {
|
next(vm => {
|
||||||
vm.utils.changeTitle('设置');
|
vm.utils.changeTitle('设置');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
config: this.$root.config.storage,
|
config: this.$root.config.storage,
|
||||||
utils: this.$root.utils
|
utils: this.$root.utils
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除数据
|
|
||||||
*
|
|
||||||
* @param {string} type 清除类型(cache、settings)
|
|
||||||
*/
|
|
||||||
resetDatas(type) {
|
|
||||||
this.$confirm('确定要清除吗?', '', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning'
|
|
||||||
}).then(() => {
|
|
||||||
|
|
||||||
if (type === 'cache') {
|
|
||||||
localStorage.removeItem('navLinksCache');
|
|
||||||
} else if (type === 'settings') {
|
|
||||||
localStorage.removeItem('navConfig');
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$message({
|
|
||||||
message: '已清除,2s 后自动刷新',
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
location.reload();
|
|
||||||
}, 2000);
|
|
||||||
|
|
||||||
}).catch(() => {
|
|
||||||
|
|
||||||
this.$message({
|
|
||||||
message: '取消清除',
|
|
||||||
type: 'info'
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除数据
|
||||||
|
*
|
||||||
|
* @param {string} type 清除类型(cache、settings)
|
||||||
|
*/
|
||||||
|
resetDatas(type) {
|
||||||
|
this.$confirm('确定要清除吗?', '', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
|
||||||
|
if (type === 'cache') {
|
||||||
|
localStorage.removeItem('navLinksCache');
|
||||||
|
} else if (type === 'settings') {
|
||||||
|
localStorage.removeItem('navConfig');
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$message({
|
||||||
|
message: '已清除,2s 后自动刷新',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
location.reload();
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
}).catch(() => {
|
||||||
|
|
||||||
|
this.$message({
|
||||||
|
message: '取消清除',
|
||||||
|
type: 'info'
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.settings {
|
.settings {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
background-color: @colorWhite;
|
background-color: @colorWhite;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
padding: 1.5rem 2rem;
|
padding: 1.5rem 2rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 50rem;
|
max-width: 50rem;
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.set-font {
|
.set-font {
|
||||||
/deep/ .el-input-number {
|
/deep/ .el-input-number {
|
||||||
width: 7rem;
|
width: 7rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .el-form-item {
|
/deep/ .el-form-item {
|
||||||
@media screen and (max-width: 520px) {
|
@media screen and (max-width: 520px) {
|
||||||
.el-form-item__label {
|
.el-form-item__label {
|
||||||
float: unset !important;
|
float: unset !important;
|
||||||
}
|
|
||||||
.el-form-item__content {
|
|
||||||
margin-left: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.el-form-item__content {
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -9,13 +9,6 @@ import navTools from '@/assets/js/navTools.js';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ToolsDetail',
|
name: 'ToolsDetail',
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
utils: this.$root.utils,
|
|
||||||
toolList: navTools,
|
|
||||||
toolPage: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
next(vm => {
|
next(vm => {
|
||||||
const { params, query } = vm.$route;
|
const { params, query } = vm.$route;
|
||||||
@@ -52,6 +45,13 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
utils: this.$root.utils,
|
||||||
|
toolList: navTools,
|
||||||
|
toolPage: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -61,16 +61,6 @@ import navTools from '@/assets/js/navTools.js';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ToolsView',
|
name: 'ToolsView',
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
utils: this.$root.utils,
|
|
||||||
toolList: navTools,
|
|
||||||
detail: {
|
|
||||||
show: false,
|
|
||||||
title: ''
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
next(vm => {
|
next(vm => {
|
||||||
const { name: rName, params: rParams } = vm.$route;
|
const { name: rName, params: rParams } = vm.$route;
|
||||||
@@ -85,6 +75,16 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
utils: this.$root.utils,
|
||||||
|
toolList: navTools,
|
||||||
|
detail: {
|
||||||
|
show: false,
|
||||||
|
title: ''
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user