mirror of
https://github.com/fantastic-admin/basic.git
synced 2026-10-07 11:34:10 +08:00
采用script、template、style的顺序优化所有sfc文件
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
<script setup{{#if isGlobal}} name="{{ properCase name }}"{{/if}}>
|
||||
// const { proxy } = getCurrentInstance()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- 内容区 -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup{{#if isGlobal}} name="{{ properCase name }}"{{/if}}>
|
||||
// const { proxy } = getCurrentInstance()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// scss
|
||||
</style>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
<script setup name="{{ properCase componentName }}">
|
||||
// const { proxy } = getCurrentInstance()
|
||||
// const router = useRouter()
|
||||
// const route = useRoute()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="{{ cname }}" />
|
||||
@@ -7,12 +13,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="{{ properCase componentName }}">
|
||||
// const { proxy } = getCurrentInstance()
|
||||
// const router = useRouter()
|
||||
// const route = useRoute()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// scss
|
||||
</style>
|
||||
|
||||
+11
-11
@@ -1,14 +1,3 @@
|
||||
<template>
|
||||
<el-config-provider :size="settingsStore.app.elementSize">
|
||||
<RouterView
|
||||
:style="{
|
||||
'--g-main-sidebar-actual-width': mainSidebarActualWidth,
|
||||
'--g-sub-sidebar-actual-width': subSidebarActualWidth
|
||||
}"
|
||||
/>
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
@@ -75,3 +64,14 @@ onMounted(() => {
|
||||
window.onresize()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-config-provider :size="settingsStore.app.elementSize">
|
||||
<RouterView
|
||||
:style="{
|
||||
'--g-main-sidebar-actual-width': mainSidebarActualWidth,
|
||||
'--g-sub-sidebar-actual-width': subSidebarActualWidth
|
||||
}"
|
||||
/>
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
<template>
|
||||
<div>
|
||||
<slot v-if="check()" />
|
||||
<slot v-else name="no-auth" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Auth">
|
||||
import { auth } from '@/util'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -19,3 +12,10 @@ function check() {
|
||||
return auth(props.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<slot v-if="check()" />
|
||||
<slot v-else name="no-auth" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
<template>
|
||||
<div>
|
||||
<slot v-if="check()" />
|
||||
<slot v-else name="no-auth" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="AuthAll">
|
||||
import { authAll } from '@/util'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -19,3 +12,10 @@ function check() {
|
||||
return authAll(props.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<slot v-if="check()" />
|
||||
<slot v-else name="no-auth" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
<template>
|
||||
<div class="batch-action-bar">
|
||||
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" :disabled="!data.length">当页全选</el-checkbox>
|
||||
<div v-if="selectionData.length" class="tips">已选 {{ selectionData.length }} 项</div>
|
||||
<el-form :disabled="!selectionData.length">
|
||||
<slot />
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="BatchActionBar">
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
@@ -44,6 +34,16 @@ const isIndeterminate = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="batch-action-bar">
|
||||
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" :disabled="!data.length">当页全选</el-checkbox>
|
||||
<div v-if="selectionData.length" class="tips">已选 {{ selectionData.length }} 项</div>
|
||||
<el-form :disabled="!selectionData.length">
|
||||
<slot />
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.batch-action-bar {
|
||||
display: flex;
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-cascader v-model="myValue" :options="data.options" :props="data.props" :size="size" :disabled="disabled" clearable filterable />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="CascaderArea">
|
||||
import area from '@/util/area'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -84,6 +78,12 @@ const myValue = computed({
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-cascader v-model="myValue" :options="data.options" :props="data.props" :size="size" :disabled="disabled" clearable filterable />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-cascader) {
|
||||
width: 100%;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<script setup name="Copyright">
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<footer class="copyright">
|
||||
Copyright © {{ settingsStore.copyright.dates }}
|
||||
@@ -7,11 +12,6 @@
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
footer {
|
||||
margin: 40px 0 20px;
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
<template>
|
||||
<div class="editor">
|
||||
<TinymceEditor v-model="myValue" :init="completeSetting" :disabled="disabled" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Editor">
|
||||
import tinymce from 'tinymce/tinymce'
|
||||
import TinymceEditor from '@tinymce/tinymce-vue'
|
||||
import 'tinymce/themes/silver/theme'
|
||||
@@ -88,6 +82,12 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="editor">
|
||||
<TinymceEditor v-model="myValue" :init="completeSetting" :disabled="disabled" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.tox-tinymce) {
|
||||
border: 1px solid #dcdfe6;
|
||||
|
||||
@@ -1,30 +1,4 @@
|
||||
<template>
|
||||
<el-upload
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-exceed="onExceed"
|
||||
:on-success="onSuccess"
|
||||
:file-list="files"
|
||||
:limit="max"
|
||||
drag
|
||||
>
|
||||
<div class="slot">
|
||||
<el-icon class="el-icon--upload"><el-icon-upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传文件支持 ${ ext.join(' / ') } 格式,单个文件大小不超过 ${ size }MB,且文件数量不超过 ${ max } 个`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="FileUpload">
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
@@ -89,6 +63,32 @@ function onSuccess(res, file) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-upload
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-exceed="onExceed"
|
||||
:on-success="onSuccess"
|
||||
:file-list="files"
|
||||
:limit="max"
|
||||
drag
|
||||
>
|
||||
<div class="slot">
|
||||
<el-icon class="el-icon--upload"><el-icon-upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传文件支持 ${ ext.join(' / ') } 格式,单个文件大小不超过 ${ size }MB,且文件数量不超过 ${ max } 个`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-upload-dragger) {
|
||||
width: auto;
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
<template>
|
||||
<div class="actionbar" :class="{'shadow': !data.isBottom}" data-fixed-calc-width>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="FixedActionBar">
|
||||
const data = ref({
|
||||
isBottom: true
|
||||
})
|
||||
@@ -34,6 +28,12 @@ function onScroll() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="actionbar" :class="{'shadow': !data.isBottom}" data-fixed-calc-width>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.actionbar {
|
||||
z-index: 4;
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
<template>
|
||||
<el-image :src="src" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="[src]">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<svg-icon name="image-load-fail" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="ImagePreview">
|
||||
const props = defineProps({
|
||||
src: {
|
||||
type: String,
|
||||
@@ -33,6 +23,16 @@ const realHeight = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-image :src="src" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="[src]">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<svg-icon name="image-load-fail" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-image {
|
||||
border-radius: 5px;
|
||||
|
||||
@@ -1,51 +1,4 @@
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<el-upload
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-progress="onProgress"
|
||||
:on-success="onSuccess"
|
||||
drag
|
||||
>
|
||||
<el-image v-if="url === ''" :src="url === '' ? placeholder : url" :style="`width:${width}px;height:${height}px;`" fit="fill">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<svg-icon name="el-icon-plus" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<div v-else class="image">
|
||||
<el-image :src="url" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<div class="mask">
|
||||
<div class="actions">
|
||||
<span title="预览" @click.stop="preview">
|
||||
<el-icon><el-icon-zoom-in /></el-icon>
|
||||
</span>
|
||||
<span title="移除" @click.stop="remove">
|
||||
<el-icon><el-icon-delete /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="url === '' && uploadData.progress.percent" class="progress" :style="`width:${width}px;height:${height}px;`">
|
||||
<el-image :src="uploadData.progress.preview" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<el-progress type="circle" :width="Math.min(width, height) * 0.8" :percentage="uploadData.progress.percent" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传图片支持 ${ ext.join(' / ') } 格式,且图片大小不超过 ${ size }MB,建议图片尺寸为 ${width}*${height}`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
<el-image-viewer v-if="uploadData.imageViewerVisible" :url-list="[url]" @close="previewClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="ImageUpload">
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
@@ -143,6 +96,53 @@ function onSuccess(res) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<el-upload
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-progress="onProgress"
|
||||
:on-success="onSuccess"
|
||||
drag
|
||||
>
|
||||
<el-image v-if="url === ''" :src="url === '' ? placeholder : url" :style="`width:${width}px;height:${height}px;`" fit="fill">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<svg-icon name="el-icon-plus" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<div v-else class="image">
|
||||
<el-image :src="url" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<div class="mask">
|
||||
<div class="actions">
|
||||
<span title="预览" @click.stop="preview">
|
||||
<el-icon><el-icon-zoom-in /></el-icon>
|
||||
</span>
|
||||
<span title="移除" @click.stop="remove">
|
||||
<el-icon><el-icon-delete /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="url === '' && uploadData.progress.percent" class="progress" :style="`width:${width}px;height:${height}px;`">
|
||||
<el-image :src="uploadData.progress.preview" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<el-progress type="circle" :width="Math.min(width, height) * 0.8" :percentage="uploadData.progress.percent" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传图片支持 ${ ext.join(' / ') } 格式,且图片大小不超过 ${ size }MB,建议图片尺寸为 ${width}*${height}`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
<el-image-viewer v-if="uploadData.imageViewerVisible" :url-list="[url]" @close="previewClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-container {
|
||||
line-height: initial;
|
||||
|
||||
@@ -1,55 +1,4 @@
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<div v-for="(item, index) in url" :key="index" class="images">
|
||||
<el-image v-if="index < max" :src="item" :style="`width:${width}px;height:${height}px;`" fit="cover" />
|
||||
<div class="mask">
|
||||
<div class="actions">
|
||||
<span title="预览" @click="preview(index)">
|
||||
<el-icon><el-icon-zoom-in /></el-icon>
|
||||
</span>
|
||||
<span title="移除" @click="remove(index)">
|
||||
<el-icon><el-icon-delete /></el-icon>
|
||||
</span>
|
||||
<span v-show="url.length > 1" title="左移" :class="{'disabled': index == 0}" @click="move(index, 'left')">
|
||||
<el-icon><el-icon-back /></el-icon>
|
||||
</span>
|
||||
<span v-show="url.length > 1" title="右移" :class="{'disabled': index == url.length - 1}" @click="move(index, 'right')">
|
||||
<el-icon><el-icon-right /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-upload
|
||||
v-show="url.length < max"
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-progress="onProgress"
|
||||
:on-success="onSuccess"
|
||||
drag
|
||||
class="images-upload"
|
||||
>
|
||||
<div class="image-slot" :style="`width:${width}px;height:${height}px;`">
|
||||
<svg-icon name="el-icon-plus" />
|
||||
</div>
|
||||
<div v-show="uploadData.progress.percent" class="progress" :style="`width:${width}px;height:${height}px;`">
|
||||
<el-image :src="uploadData.progress.preview" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<el-progress type="circle" :width="Math.min(width, height) * 0.8" :percentage="uploadData.progress.percent" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传图片支持 ${ ext.join(' / ') } 格式,单张图片大小不超过 ${ size }MB,建议图片尺寸为 ${width}*${height},且图片数量不超过 ${ max } 张`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
<el-image-viewer v-if="uploadData.imageViewerVisible" :url-list="url" :initial-index="uploadData.dialogImageIndex" @close="previewClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="ImagesUpload">
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
@@ -166,6 +115,57 @@ function onSuccess(res) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<div v-for="(item, index) in url" :key="index" class="images">
|
||||
<el-image v-if="index < max" :src="item" :style="`width:${width}px;height:${height}px;`" fit="cover" />
|
||||
<div class="mask">
|
||||
<div class="actions">
|
||||
<span title="预览" @click="preview(index)">
|
||||
<el-icon><el-icon-zoom-in /></el-icon>
|
||||
</span>
|
||||
<span title="移除" @click="remove(index)">
|
||||
<el-icon><el-icon-delete /></el-icon>
|
||||
</span>
|
||||
<span v-show="url.length > 1" title="左移" :class="{'disabled': index == 0}" @click="move(index, 'left')">
|
||||
<el-icon><el-icon-back /></el-icon>
|
||||
</span>
|
||||
<span v-show="url.length > 1" title="右移" :class="{'disabled': index == url.length - 1}" @click="move(index, 'right')">
|
||||
<el-icon><el-icon-right /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-upload
|
||||
v-show="url.length < max"
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-progress="onProgress"
|
||||
:on-success="onSuccess"
|
||||
drag
|
||||
class="images-upload"
|
||||
>
|
||||
<div class="image-slot" :style="`width:${width}px;height:${height}px;`">
|
||||
<svg-icon name="el-icon-plus" />
|
||||
</div>
|
||||
<div v-show="uploadData.progress.percent" class="progress" :style="`width:${width}px;height:${height}px;`">
|
||||
<el-image :src="uploadData.progress.preview" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<el-progress type="circle" :width="Math.min(width, height) * 0.8" :percentage="uploadData.progress.percent" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传图片支持 ${ ext.join(' / ') } 格式,单张图片大小不超过 ${ size }MB,建议图片尺寸为 ${width}*${height},且图片数量不超过 ${ max } 张`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
<el-image-viewer v-if="uploadData.imageViewerVisible" :url-list="url" :initial-index="uploadData.dialogImageIndex" @close="previewClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-container {
|
||||
line-height: initial;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
<script setup name="PageHeader">
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="main">
|
||||
@@ -12,19 +25,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.header {
|
||||
display: flex;
|
||||
|
||||
@@ -1,21 +1,4 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'page-main': true,
|
||||
'is-collaspe': collaspeData
|
||||
}" :style="{
|
||||
'height': collaspeData ? height : ''
|
||||
}"
|
||||
>
|
||||
<div v-if="title" class="title-container">{{ title }}</div>
|
||||
<slot />
|
||||
<div v-if="collaspeData" class="collaspe" title="展开" @click="unCollaspe">
|
||||
<el-icon><el-icon-arrow-down /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="PageMain">
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
@@ -38,6 +21,23 @@ function unCollaspe() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'page-main': true,
|
||||
'is-collaspe': collaspeData
|
||||
}" :style="{
|
||||
'height': collaspeData ? height : ''
|
||||
}"
|
||||
>
|
||||
<div v-if="title" class="title-container">{{ title }}</div>
|
||||
<slot />
|
||||
<div v-if="collaspeData" class="collaspe" title="展开" @click="unCollaspe">
|
||||
<el-icon><el-icon-arrow-down /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-main {
|
||||
position: relative;
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
<script setup name="Result">
|
||||
defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
validator: val => ['success', 'warning', 'error'].includes(val),
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
desc: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="result">
|
||||
<div v-if="type === 'success'" class="icon icon-success">
|
||||
@@ -20,24 +38,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
validator: val => ['success', 'warning', 'error'].includes(val),
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
desc: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$success: #67c23a;
|
||||
$warning: #e6a23c;
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
<template>
|
||||
<div class="search-container">
|
||||
<slot />
|
||||
<div v-if="showMore" class="more">
|
||||
<el-button type="text" size="small" :icon="isUnfold ? 'el-icon-caret-top' : 'el-icon-caret-bottom'" @click="toggle">{{ isUnfold ? '收起' : '展开' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="SearchBar">
|
||||
const props = defineProps({
|
||||
showMore: {
|
||||
type: Boolean,
|
||||
@@ -33,6 +24,15 @@ function toggle() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="search-container">
|
||||
<slot />
|
||||
<div v-if="showMore" class="more">
|
||||
<el-button type="text" size="small" :icon="isUnfold ? 'el-icon-caret-top' : 'el-icon-caret-bottom'" @click="toggle">{{ isUnfold ? '收起' : '展开' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-container {
|
||||
position: relative;
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
<template>
|
||||
<el-icon v-if="name.indexOf('el-icon-') === 0 || name.indexOf('ElIcon') === 0" class="svg-icon" :style="transformStyle">
|
||||
<Component :is="name" />
|
||||
</el-icon>
|
||||
<svg v-else class="svg-icon" :style="transformStyle" aria-hidden="true">
|
||||
<use :xlink:href="`#icon-${name}`" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="SvgIcon">
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
@@ -52,12 +43,21 @@ const transformStyle = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-icon v-if="name.indexOf('el-icon-') === 0 || name.indexOf('ElIcon') === 0" class="svg-icon" :style="transformStyle">
|
||||
<Component :is="name" />
|
||||
</el-icon>
|
||||
<svg v-else class="svg-icon" :style="transformStyle" aria-hidden="true">
|
||||
<use :xlink:href="`#icon-${name}`" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
fill: currentcolor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
<template>
|
||||
<div class="adaption-container">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="TableHeightAdaption">
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
@@ -18,6 +12,12 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="adaption-container">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.adaption-container {
|
||||
height: 100%;
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
<template>
|
||||
<div :class="`trend ${isUp ? 'up' : 'down'}`">
|
||||
<span v-if="prefix" class="prefix">{{ prefix }}</span>
|
||||
<span class="text">{{ value }}</span>
|
||||
<span v-if="suffix" class="suffix">{{ suffix }}</span>
|
||||
<svg-icon :name="`${isUp ? 'el-icon-caret-top' : 'el-icon-caret-bottom'}`" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Trend">
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: String,
|
||||
@@ -41,6 +32,15 @@ const isUp = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="`trend ${isUp ? 'up' : 'down'}`">
|
||||
<span v-if="prefix" class="prefix">{{ prefix }}</span>
|
||||
<span class="text">{{ value }}</span>
|
||||
<span v-if="suffix" class="suffix">{{ suffix }}</span>
|
||||
<svg-icon :name="`${isUp ? 'el-icon-caret-top' : 'el-icon-caret-bottom'}`" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.trend {
|
||||
display: inline-block;
|
||||
|
||||
@@ -1,3 +1,45 @@
|
||||
<script setup name="AppSetting">
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const isShow = ref(false)
|
||||
|
||||
import globalSettings from '@/settings'
|
||||
const settings = ref(globalSettings)
|
||||
|
||||
watch(() => settings, () => {
|
||||
settingsStore.updateThemeSetting(settings.value)
|
||||
menuStore.setActived(0)
|
||||
settings.value.menu.menuMode !== 'single' && menuStore.setActived(route.fullPath)
|
||||
}, {
|
||||
deep: true
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
proxy.$eventBus.on('global-theme-toggle', () => {
|
||||
isShow.value = !isShow.value
|
||||
})
|
||||
})
|
||||
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
const { copy, copied, isSupported } = useClipboard()
|
||||
|
||||
watch(copied, val => {
|
||||
if (val) {
|
||||
proxy.$message.success('复制成功,请粘贴到 src/settings.custom.json 文件中!')
|
||||
}
|
||||
})
|
||||
|
||||
function handleCopy() {
|
||||
copy(JSON.stringify(settings.value, null, 4))
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer v-model="isShow" title="应用配置" direction="rtl" :size="350" custom-class="flex-container">
|
||||
@@ -163,48 +205,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const isShow = ref(false)
|
||||
|
||||
import globalSettings from '@/settings'
|
||||
const settings = ref(globalSettings)
|
||||
|
||||
watch(() => settings, () => {
|
||||
settingsStore.updateThemeSetting(settings.value)
|
||||
menuStore.setActived(0)
|
||||
settings.value.menu.menuMode !== 'single' && menuStore.setActived(route.fullPath)
|
||||
}, {
|
||||
deep: true
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
proxy.$eventBus.on('global-theme-toggle', () => {
|
||||
isShow.value = !isShow.value
|
||||
})
|
||||
})
|
||||
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
const { copy, copied, isSupported } = useClipboard()
|
||||
|
||||
watch(copied, val => {
|
||||
if (val) {
|
||||
proxy.$message.success('复制成功,请粘贴到 src/settings.custom.json 文件中!')
|
||||
}
|
||||
})
|
||||
|
||||
function handleCopy() {
|
||||
copy(JSON.stringify(settings.value, null, 4))
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-drawer__body) {
|
||||
display: flex;
|
||||
|
||||
@@ -1,29 +1,4 @@
|
||||
<template>
|
||||
<div class="buy-it" :class="{'actived': isActived}">
|
||||
<div class="item" @click="open('https://wpa.qq.com/msgrd?v=3&uin=304327508&site=qq&menu=yes')">
|
||||
<svg-icon name="fixed-right-qq" />
|
||||
<span class="title">在线<br>咨询</span>
|
||||
</div>
|
||||
<div class="item chat" @click="open('https://qm.qq.com/cgi-bin/qm/qr?k=WoDBYN0S9r94f9oBZkxlGbiYxu3dEzgt&jump_from=webapi')">
|
||||
<svg-icon name="fixed-right-chat" />
|
||||
<span class="title">加入<br>QQ群</span>
|
||||
</div>
|
||||
<div class="item buy" @click="open(`https://hooray.${locationOrigin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/buy.html`)">
|
||||
<svg-icon name="fixed-right-buy" />
|
||||
<span class="title">购买<br>专业版</span>
|
||||
</div>
|
||||
<div class="item doc" @click="open(`https://hooray.${locationOrigin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/`)">
|
||||
<svg-icon name="fixed-right-doc" />
|
||||
<span class="title">开发<br>文档</span>
|
||||
</div>
|
||||
<div class="item code" @click="open(`https://${locationOrigin.includes('gitee') ? 'gitee' : 'github'}.com/hooray/fantastic-admin/`)">
|
||||
<svg-icon name="fixed-right-code" />
|
||||
<span class="title">下载<br>基础版</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="BuyIt">
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const locationOrigin = ref(location.href)
|
||||
@@ -64,6 +39,31 @@ function open(url) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="buy-it" :class="{'actived': isActived}">
|
||||
<div class="item" @click="open('https://wpa.qq.com/msgrd?v=3&uin=304327508&site=qq&menu=yes')">
|
||||
<svg-icon name="fixed-right-qq" />
|
||||
<span class="title">在线<br>咨询</span>
|
||||
</div>
|
||||
<div class="item chat" @click="open('https://qm.qq.com/cgi-bin/qm/qr?k=WoDBYN0S9r94f9oBZkxlGbiYxu3dEzgt&jump_from=webapi')">
|
||||
<svg-icon name="fixed-right-chat" />
|
||||
<span class="title">加入<br>QQ群</span>
|
||||
</div>
|
||||
<div class="item buy" @click="open(`https://hooray.${locationOrigin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/buy.html`)">
|
||||
<svg-icon name="fixed-right-buy" />
|
||||
<span class="title">购买<br>专业版</span>
|
||||
</div>
|
||||
<div class="item doc" @click="open(`https://hooray.${locationOrigin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/`)">
|
||||
<svg-icon name="fixed-right-doc" />
|
||||
<span class="title">开发<br>文档</span>
|
||||
</div>
|
||||
<div class="item code" @click="open(`https://${locationOrigin.includes('gitee') ? 'gitee' : 'github'}.com/hooray/fantastic-admin/`)">
|
||||
<svg-icon name="fixed-right-code" />
|
||||
<span class="title">下载<br>基础版</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.buy-it {
|
||||
position: fixed;
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
<script setup name="Header">
|
||||
import Logo from '../Logo/index.vue'
|
||||
import Tools from '../Tools/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const switchMenu = inject('switchMenu')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<transition name="header">
|
||||
<header v-if="settingsStore.mode === 'pc' && settingsStore.menu.menuMode === 'head'">
|
||||
@@ -20,18 +32,6 @@
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Logo from '../Logo/index.vue'
|
||||
import Tools from '../Tools/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const switchMenu = inject('switchMenu')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 头部动画
|
||||
.header-enter-active {
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
<template>
|
||||
<router-link :to="to" class="title" :class="{'is-link': settingsStore.dashboard.enable}" :title="title">
|
||||
<img v-if="showLogo" :src="logo" class="logo">
|
||||
<span v-if="showTitle">{{ title }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Logo">
|
||||
import imgLogo from '@/assets/images/logo.png'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
@@ -34,6 +27,13 @@ const to = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-link :to="to" class="title" :class="{'is-link': settingsStore.dashboard.enable}" :title="title">
|
||||
<img v-if="showLogo" :src="logo" class="logo">
|
||||
<span v-if="showTitle">{{ title }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.title {
|
||||
position: fixed;
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
<script setup name="MainSidebar">
|
||||
import Logo from '../Logo/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const switchMenu = inject('switchMenu')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<transition name="main-sidebar">
|
||||
<div v-if="settingsStore.menu.menuMode === 'side' || (settingsStore.mode === 'mobile' && settingsStore.menu.menuMode !== 'single')" class="main-sidebar-container">
|
||||
@@ -20,17 +31,6 @@
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Logo from '../Logo/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const switchMenu = inject('switchMenu')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 主侧边栏动画
|
||||
.main-sidebar-enter-active {
|
||||
|
||||
@@ -1,57 +1,4 @@
|
||||
<template>
|
||||
<teleport to="#app">
|
||||
<div id="search" :class="{'searching': isShow}" @click="isShow && $eventBus.emit('global-search-toggle')">
|
||||
<div class="container">
|
||||
<div class="search-box" @click.stop>
|
||||
<el-input ref="input" v-model="searchInput" prefix-icon="el-icon-search" placeholder="搜索页面,支持标题、URL模糊查询" clearable @keydown.esc="$eventBus.emit('global-search-toggle')" @keydown.up.prevent="keyUp" @keydown.down.prevent="keyDown" @keydown.enter.prevent="keyEnter" />
|
||||
<div v-if="settingsStore.mode === 'pc'" class="tips">
|
||||
<div class="tip">
|
||||
<span>Alt</span>+<span>S</span>
|
||||
唤醒搜索面板
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span><svg-icon name="search-up" /></span>
|
||||
<span><svg-icon name="search-down" /></span>
|
||||
切换搜索结果
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span><svg-icon name="search-enter" /></span>
|
||||
访问页面
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span>ESC</span>
|
||||
退出
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="search" class="result" :class="{'mobile': settingsStore.mode === 'mobile'}">
|
||||
<router-link v-for="(item, index) in resultList" :key="item.path" v-slot="{ href, navigate }" custom :to="isShow ? item.path : ''">
|
||||
<a :ref="`search-item-${index}`" :href="isExternalLink(item.path) ? item.path : href" class="item" :class="{'actived': index === actived}" :target="isExternalLink(item.path) ? '_blank' : '_self'" @click="navigate" @mouseover="actived = index">
|
||||
<div class="icon">
|
||||
<svg-icon v-if="item.icon" :name="item.icon" />
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">
|
||||
{{ item.title }}
|
||||
<svg-icon v-if="item.isExternalLink" name="external-link" />
|
||||
</div>
|
||||
<div class="breadcrumb">
|
||||
<span v-for="(bc, bcIndex) in item.breadcrumb" :key="bcIndex">
|
||||
{{ bc }}
|
||||
<svg-icon name="el-icon-arrow-right" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="path">{{ item.path }}</div>
|
||||
</div>
|
||||
</a>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Search">
|
||||
import { deepClone, isExternalLink } from '@/util'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
@@ -212,6 +159,59 @@ function scrollTo(offsetTop) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<teleport to="#app">
|
||||
<div id="search" :class="{'searching': isShow}" @click="isShow && $eventBus.emit('global-search-toggle')">
|
||||
<div class="container">
|
||||
<div class="search-box" @click.stop>
|
||||
<el-input ref="input" v-model="searchInput" prefix-icon="el-icon-search" placeholder="搜索页面,支持标题、URL模糊查询" clearable @keydown.esc="$eventBus.emit('global-search-toggle')" @keydown.up.prevent="keyUp" @keydown.down.prevent="keyDown" @keydown.enter.prevent="keyEnter" />
|
||||
<div v-if="settingsStore.mode === 'pc'" class="tips">
|
||||
<div class="tip">
|
||||
<span>Alt</span>+<span>S</span>
|
||||
唤醒搜索面板
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span><svg-icon name="search-up" /></span>
|
||||
<span><svg-icon name="search-down" /></span>
|
||||
切换搜索结果
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span><svg-icon name="search-enter" /></span>
|
||||
访问页面
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span>ESC</span>
|
||||
退出
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="search" class="result" :class="{'mobile': settingsStore.mode === 'mobile'}">
|
||||
<router-link v-for="(item, index) in resultList" :key="item.path" v-slot="{ href, navigate }" custom :to="isShow ? item.path : ''">
|
||||
<a :ref="`search-item-${index}`" :href="isExternalLink(item.path) ? item.path : href" class="item" :class="{'actived': index === actived}" :target="isExternalLink(item.path) ? '_blank' : '_self'" @click="navigate" @mouseover="actived = index">
|
||||
<div class="icon">
|
||||
<svg-icon v-if="item.icon" :name="item.icon" />
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">
|
||||
{{ item.title }}
|
||||
<svg-icon v-if="item.isExternalLink" name="external-link" />
|
||||
</div>
|
||||
<div class="breadcrumb">
|
||||
<span v-for="(bc, bcIndex) in item.breadcrumb" :key="bcIndex">
|
||||
{{ bc }}
|
||||
<svg-icon name="el-icon-arrow-right" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="path">{{ item.path }}</div>
|
||||
</div>
|
||||
</a>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#search {
|
||||
position: fixed;
|
||||
|
||||
@@ -1,31 +1,4 @@
|
||||
<template>
|
||||
<div v-if="item.meta.sidebar !== false" class="sidebar-item">
|
||||
<el-sub-menu v-if="item.path == undefined" :title="item.meta.title" :index="JSON.stringify(item)">
|
||||
<template #title>
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" />
|
||||
</el-sub-menu>
|
||||
<router-link v-else-if="!hasChildren" v-slot="{ href, navigate, isActive, isExactActive }" custom :to="resolveRoutePath(basePath, item.path)">
|
||||
<a :href="isExternalLink(resolveRoutePath(basePath, item.path)) ? resolveRoutePath(basePath, item.path) : href" :class="[isActive && 'router-link-active', isExactActive && 'router-link-exact-active']" :target="isExternalLink(resolveRoutePath(basePath, item.path)) ? '_blank' : '_self'" @click="navigate">
|
||||
<el-menu-item :title="item.meta.title" :index="resolveRoutePath(basePath, item.path)">
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</a>
|
||||
</router-link>
|
||||
<el-sub-menu v-else :title="item.meta.title" :index="resolveRoutePath(basePath, item.path)">
|
||||
<template #title>
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" :base-path="resolveRoutePath(basePath, item.path)" />
|
||||
</el-sub-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="SidebarItem">
|
||||
import SidebarItem from './index.vue'
|
||||
import { isExternalLink, resolveRoutePath } from '@/util'
|
||||
|
||||
@@ -53,6 +26,33 @@ const hasChildren = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="item.meta.sidebar !== false" class="sidebar-item">
|
||||
<el-sub-menu v-if="item.path == undefined" :title="item.meta.title" :index="JSON.stringify(item)">
|
||||
<template #title>
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" />
|
||||
</el-sub-menu>
|
||||
<router-link v-else-if="!hasChildren" v-slot="{ href, navigate, isActive, isExactActive }" custom :to="resolveRoutePath(basePath, item.path)">
|
||||
<a :href="isExternalLink(resolveRoutePath(basePath, item.path)) ? resolveRoutePath(basePath, item.path) : href" :class="[isActive && 'router-link-active', isExactActive && 'router-link-exact-active']" :target="isExternalLink(resolveRoutePath(basePath, item.path)) ? '_blank' : '_self'" @click="navigate">
|
||||
<el-menu-item :title="item.meta.title" :index="resolveRoutePath(basePath, item.path)">
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</a>
|
||||
</router-link>
|
||||
<el-sub-menu v-else :title="item.meta.title" :index="resolveRoutePath(basePath, item.path)">
|
||||
<template #title>
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" :base-path="resolveRoutePath(basePath, item.path)" />
|
||||
</el-sub-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-menu-item),
|
||||
:deep(.el-menu-item span.title),
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
<script setup name="SubSidebar">
|
||||
import Logo from '../Logo/index.vue'
|
||||
import SidebarItem from '../SidebarItem/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const sidebarScrollTop = ref(0)
|
||||
|
||||
function onSidebarScroll(e) {
|
||||
sidebarScrollTop.value = e.target.scrollTop
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="['side', 'head', 'single'].includes(settingsStore.menu.menuMode) || settingsStore.mode === 'mobile'" class="sub-sidebar-container" :class="{'is-collapse': settingsStore.mode === 'pc' && settingsStore.menu.subMenuCollapse}" @scroll="onSidebarScroll">
|
||||
<Logo
|
||||
@@ -22,22 +38,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Logo from '../Logo/index.vue'
|
||||
import SidebarItem from '../SidebarItem/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const sidebarScrollTop = ref(0)
|
||||
|
||||
function onSidebarScroll(e) {
|
||||
sidebarScrollTop.value = e.target.scrollTop
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 次侧边栏动画
|
||||
.sub-sidebar-enter-active {
|
||||
|
||||
@@ -1,3 +1,41 @@
|
||||
<script setup name="Tools">
|
||||
const reload = inject('reload')
|
||||
const router = useRouter()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore()
|
||||
|
||||
import { useFullscreen } from '@vueuse/core'
|
||||
const { isFullscreen, toggle } = useFullscreen()
|
||||
|
||||
function userCommand(command) {
|
||||
switch (command) {
|
||||
case 'dashboard':
|
||||
router.push({
|
||||
name: 'dashboard'
|
||||
})
|
||||
break
|
||||
case 'setting':
|
||||
router.push({
|
||||
name: 'personalSetting'
|
||||
})
|
||||
break
|
||||
case 'logout':
|
||||
userStore.logout().then(() => {
|
||||
router.push({
|
||||
name: 'login'
|
||||
})
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
function pro() {
|
||||
window.open(`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/vue3/pro`, 'top')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tools">
|
||||
<div class="buttons">
|
||||
@@ -37,44 +75,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const reload = inject('reload')
|
||||
const router = useRouter()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore()
|
||||
|
||||
import { useFullscreen } from '@vueuse/core'
|
||||
const { isFullscreen, toggle } = useFullscreen()
|
||||
|
||||
function userCommand(command) {
|
||||
switch (command) {
|
||||
case 'dashboard':
|
||||
router.push({
|
||||
name: 'dashboard'
|
||||
})
|
||||
break
|
||||
case 'setting':
|
||||
router.push({
|
||||
name: 'personalSetting'
|
||||
})
|
||||
break
|
||||
case 'logout':
|
||||
userStore.logout().then(() => {
|
||||
router.push({
|
||||
name: 'login'
|
||||
})
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
function pro() {
|
||||
window.open(`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/vue3/pro`, 'top')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tools {
|
||||
display: flex;
|
||||
|
||||
@@ -1,32 +1,4 @@
|
||||
<template>
|
||||
<div
|
||||
class="topbar-container" :class="{
|
||||
'fixed': settingsStore.topbar.fixed,
|
||||
'shadow': scrollTop
|
||||
}" data-fixed-calc-width
|
||||
>
|
||||
<div class="left-box">
|
||||
<div v-if="enableSidebarCollapse" class="sidebar-collapse" :class="{'is-collapse': settingsStore.menu.subMenuCollapse}" @click="settingsStore.toggleSidebarCollapse()">
|
||||
<svg-icon name="toolbar-collapse" />
|
||||
</div>
|
||||
<el-breadcrumb v-if="settingsStore.topbar.enableBreadcrumb && settingsStore.mode === 'pc'" separator-class="el-icon-arrow-right">
|
||||
<transition-group name="breadcrumb">
|
||||
<template v-for="(item, index) in breadcrumbList">
|
||||
<el-breadcrumb-item v-if="index < breadcrumbList.length - 1" :key="item.path" :to="pathCompile(item.path)">
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-else :key="item.path">
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
</template>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<Tools />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Topbar">
|
||||
import { compile } from 'path-to-regexp'
|
||||
import { deepClone } from '@/util'
|
||||
import Tools from '../Tools/index.vue'
|
||||
@@ -74,6 +46,34 @@ function pathCompile(path) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="topbar-container" :class="{
|
||||
'fixed': settingsStore.topbar.fixed,
|
||||
'shadow': scrollTop
|
||||
}" data-fixed-calc-width
|
||||
>
|
||||
<div class="left-box">
|
||||
<div v-if="enableSidebarCollapse" class="sidebar-collapse" :class="{'is-collapse': settingsStore.menu.subMenuCollapse}" @click="settingsStore.toggleSidebarCollapse()">
|
||||
<svg-icon name="toolbar-collapse" />
|
||||
</div>
|
||||
<el-breadcrumb v-if="settingsStore.topbar.enableBreadcrumb && settingsStore.mode === 'pc'" separator-class="el-icon-arrow-right">
|
||||
<transition-group name="breadcrumb">
|
||||
<template v-for="(item, index) in breadcrumbList">
|
||||
<el-breadcrumb-item v-if="index < breadcrumbList.length - 1" :key="item.path" :to="pathCompile(item.path)">
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-else :key="item.path">
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
</template>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<Tools />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.topbar-container {
|
||||
position: absolute;
|
||||
|
||||
+34
-34
@@ -1,37 +1,4 @@
|
||||
<template>
|
||||
<div class="layout">
|
||||
<div id="app-main">
|
||||
<Header />
|
||||
<div class="wrapper">
|
||||
<div class="sidebar-container" :class="{'show': settingsStore.mode === 'mobile' && !settingsStore.menu.subMenuCollapse}">
|
||||
<MainSidebar />
|
||||
<SubSidebar />
|
||||
</div>
|
||||
<div class="sidebar-mask" :class="{'show': settingsStore.mode === 'mobile' && !settingsStore.menu.subMenuCollapse}" @click="settingsStore.toggleSidebarCollapse()" />
|
||||
<div class="main-container" :style="{'padding-bottom': $route.meta.paddingBottom}">
|
||||
<Topbar v-if="!(settingsStore.menu.menuMode === 'head' && !settingsStore.topbar.enableSidebarCollapse && !settingsStore.topbar.enableBreadcrumb)" />
|
||||
<div class="main">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition name="main" mode="out-in" appear>
|
||||
<!-- BUG https://github.com/vuejs/vue-next/issues/4984 -->
|
||||
<keep-alive :include="[...keepAliveStore.list]">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</div>
|
||||
<Copyright v-if="showCopyright" />
|
||||
</div>
|
||||
</div>
|
||||
<el-backtop :right="20" :bottom="20" title="回到顶部" />
|
||||
</div>
|
||||
<Search />
|
||||
<AppSetting />
|
||||
<BuyIt />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Layout">
|
||||
import Header from './components/Header/index.vue'
|
||||
import MainSidebar from './components/MainSidebar/index.vue'
|
||||
import SubSidebar from './components/SubSidebar/index.vue'
|
||||
@@ -101,6 +68,39 @@ function switchMenu(index) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layout">
|
||||
<div id="app-main">
|
||||
<Header />
|
||||
<div class="wrapper">
|
||||
<div class="sidebar-container" :class="{'show': settingsStore.mode === 'mobile' && !settingsStore.menu.subMenuCollapse}">
|
||||
<MainSidebar />
|
||||
<SubSidebar />
|
||||
</div>
|
||||
<div class="sidebar-mask" :class="{'show': settingsStore.mode === 'mobile' && !settingsStore.menu.subMenuCollapse}" @click="settingsStore.toggleSidebarCollapse()" />
|
||||
<div class="main-container" :style="{'padding-bottom': $route.meta.paddingBottom}">
|
||||
<Topbar v-if="!(settingsStore.menu.menuMode === 'head' && !settingsStore.topbar.enableSidebarCollapse && !settingsStore.topbar.enableBreadcrumb)" />
|
||||
<div class="main">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition name="main" mode="out-in" appear>
|
||||
<!-- BUG https://github.com/vuejs/vue-next/issues/4984 -->
|
||||
<keep-alive :include="[...keepAliveStore.list]">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</div>
|
||||
<Copyright v-if="showCopyright" />
|
||||
</div>
|
||||
</div>
|
||||
<el-backtop :right="20" :bottom="20" title="回到顶部" />
|
||||
</div>
|
||||
<Search />
|
||||
<AppSetting />
|
||||
<BuyIt />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
[data-mode="mobile"] {
|
||||
.sidebar-container {
|
||||
|
||||
+11
-11
@@ -1,14 +1,3 @@
|
||||
<template>
|
||||
<div class="notfound">
|
||||
<svg-icon name="404" />
|
||||
<div class="content">
|
||||
<h1>404</h1>
|
||||
<div class="desc">抱歉,你访问的页面不存在</div>
|
||||
<el-button type="primary" @click="goBack">{{ data.countdown }} 秒后,返回首页</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onBeforeRouteLeave } from 'vue-router'
|
||||
const router = useRouter()
|
||||
@@ -37,6 +26,17 @@ function goBack() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="notfound">
|
||||
<svg-icon name="404" />
|
||||
<div class="content">
|
||||
<h1>404</h1>
|
||||
<div class="desc">抱歉,你访问的页面不存在</div>
|
||||
<el-button type="primary" @click="goBack">{{ data.countdown }} 秒后,返回首页</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notfound {
|
||||
display: flex;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<script setup>
|
||||
import Alert from './components/alert.vue'
|
||||
import { Search, Edit, Check, Message, Star, Delete, Share, ArrowLeft } from '@element-plus/icons-vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -97,11 +102,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Alert from './components/alert.vue'
|
||||
import { Search, Edit, Check, Message, Star, Delete, Share, ArrowLeft } from '@element-plus/icons-vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo {
|
||||
.el-row {
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
const cityOptions = ['上海', '北京', '广州', '深圳']
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
checked: true,
|
||||
checked1: false,
|
||||
checked2: true,
|
||||
checkList: ['选中且禁用', '复选框 A'],
|
||||
checkedCities: ['上海', '北京'],
|
||||
cities: cityOptions,
|
||||
checkboxGroup1: ['上海'],
|
||||
checked3: true,
|
||||
checked4: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -34,28 +59,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
const cityOptions = ['上海', '北京', '广州', '深圳']
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
checked: true,
|
||||
checked1: false,
|
||||
checked2: true,
|
||||
checkList: ['选中且禁用', '复选框 A'],
|
||||
checkedCities: ['上海', '北京'],
|
||||
cities: cityOptions,
|
||||
checkboxGroup1: ['上海'],
|
||||
checked3: true,
|
||||
checked4: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,32 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="日期选择器" />
|
||||
<page-main title="选择日" class="demo">
|
||||
<div>默认</div>
|
||||
<el-date-picker v-model="value1" type="date" placeholder="选择日期" />
|
||||
<div>带快捷选项</div>
|
||||
<el-date-picker v-model="value2" align="right" type="date" placeholder="选择日期" :disabled-date="disabledDate" :shortcuts="shortcuts" />
|
||||
</page-main>
|
||||
<page-main title="其他日期单位" class="demo">
|
||||
<div>周</div>
|
||||
<el-date-picker v-model="value3" type="week" format="gggg 第 ww 周" placeholder="选择周" />
|
||||
<div>月</div>
|
||||
<el-date-picker v-model="value4" type="month" placeholder="选择月" />
|
||||
<div>年</div>
|
||||
<el-date-picker v-model="value5" type="year" placeholder="选择年" />
|
||||
<div>多个日期</div>
|
||||
<el-date-picker v-model="value6" type="dates" placeholder="选择一个或多个日期" />
|
||||
</page-main>
|
||||
<page-main title="选择日期范围" class="demo">
|
||||
<el-date-picker v-model="value7" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||
</page-main>
|
||||
<page-main title="选择月份范围" class="demo">
|
||||
<el-date-picker v-model="value8" type="monthrange" range-separator="至" start-placeholder="开始月份" end-placeholder="结束月份" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
@@ -73,3 +44,32 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="日期选择器" />
|
||||
<page-main title="选择日" class="demo">
|
||||
<div>默认</div>
|
||||
<el-date-picker v-model="value1" type="date" placeholder="选择日期" />
|
||||
<div>带快捷选项</div>
|
||||
<el-date-picker v-model="value2" align="right" type="date" placeholder="选择日期" :disabled-date="disabledDate" :shortcuts="shortcuts" />
|
||||
</page-main>
|
||||
<page-main title="其他日期单位" class="demo">
|
||||
<div>周</div>
|
||||
<el-date-picker v-model="value3" type="week" format="gggg 第 ww 周" placeholder="选择周" />
|
||||
<div>月</div>
|
||||
<el-date-picker v-model="value4" type="month" placeholder="选择月" />
|
||||
<div>年</div>
|
||||
<el-date-picker v-model="value5" type="year" placeholder="选择年" />
|
||||
<div>多个日期</div>
|
||||
<el-date-picker v-model="value6" type="dates" placeholder="选择一个或多个日期" />
|
||||
</page-main>
|
||||
<page-main title="选择日期范围" class="demo">
|
||||
<el-date-picker v-model="value7" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||
</page-main>
|
||||
<page-main title="选择月份范围" class="demo">
|
||||
<el-date-picker v-model="value8" type="monthrange" range-separator="至" start-placeholder="开始月份" end-placeholder="结束月份" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="日期时间选择器" />
|
||||
<page-main title="日期和时间点" class="demo">
|
||||
<el-date-picker v-model="value1" type="datetime" placeholder="选择日期时间" />
|
||||
</page-main>
|
||||
<page-main title="日期和时间范围" class="demo">
|
||||
<el-date-picker v-model="value2" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||
</page-main>
|
||||
<page-main title="默认的起始与结束时刻" class="demo">
|
||||
<div>起始日期时刻为 12:00:00,结束日期时刻为 08:00:00</div>
|
||||
<el-date-picker v-model="value3" type="datetimerange" align="right" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date(2000, 1, 1, 12, 0, 0), new Date(2000, 2, 1, 8, 0, 0)]" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
@@ -31,3 +14,20 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="日期时间选择器" />
|
||||
<page-main title="日期和时间点" class="demo">
|
||||
<el-date-picker v-model="value1" type="datetime" placeholder="选择日期时间" />
|
||||
</page-main>
|
||||
<page-main title="日期和时间范围" class="demo">
|
||||
<el-date-picker v-model="value2" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" />
|
||||
</page-main>
|
||||
<page-main title="默认的起始与结束时刻" class="demo">
|
||||
<div>起始日期时刻为 12:00:00,结束日期时刻为 08:00:00</div>
|
||||
<el-date-picker v-model="value3" type="datetimerange" align="right" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date(2000, 1, 1, 12, 0, 0), new Date(2000, 2, 1, 8, 0, 0)]" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
<script setup>
|
||||
import Alert from './components/alert.vue'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import * as ElementIcons from '@element-plus/icons-vue'
|
||||
import { hyphen } from 'naming-style'
|
||||
|
||||
const icon = Object.keys(ElementIcons)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -20,15 +29,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Alert from './components/alert.vue'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import * as ElementIcons from '@element-plus/icons-vue'
|
||||
import { hyphen } from 'naming-style'
|
||||
|
||||
const icon = Object.keys(ElementIcons)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo {
|
||||
> .el-icon {
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
input: '',
|
||||
input1: '',
|
||||
input2: '',
|
||||
textarea: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -17,12 +35,12 @@
|
||||
<page-main title="带 icon 的输入框" class="demo">
|
||||
<el-input v-model="input1" placeholder="请选择日期">
|
||||
<template #suffix>
|
||||
<el-icon><el-icon-calendar /></el-icon>
|
||||
<el-icon class="el-input__icon"><el-icon-calendar /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-input v-model="input2" placeholder="请输入内容">
|
||||
<template #prefix>
|
||||
<el-icon><el-icon-search /></el-icon>
|
||||
<el-icon class="el-input__icon"><el-icon-search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</page-main>
|
||||
@@ -31,21 +49,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
input: '',
|
||||
input1: '',
|
||||
input2: '',
|
||||
textarea: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
num: 1,
|
||||
num2: 1,
|
||||
num3: 5,
|
||||
num4: 1,
|
||||
num5: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -19,22 +38,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
num: 1,
|
||||
num2: 1,
|
||||
num3: 5,
|
||||
num4: 1,
|
||||
num5: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<script setup>
|
||||
import Alert from './components/alert.vue'
|
||||
import { Edit } from '@element-plus/icons-vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -32,11 +37,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Alert from './components/alert.vue'
|
||||
import { Edit } from '@element-plus/icons-vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo {
|
||||
.el-link {
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
radio: '1',
|
||||
radio2: '选中且禁用',
|
||||
radio3: 3,
|
||||
radio4: '上海',
|
||||
radio5: '1'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -31,22 +50,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
radio: '1',
|
||||
radio2: '选中且禁用',
|
||||
radio3: 3,
|
||||
radio4: '上海',
|
||||
radio5: '1'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="评分" />
|
||||
<page-main title="基础用法" class="demo">
|
||||
<el-rate v-model="value1" />
|
||||
</page-main>
|
||||
<page-main title="辅助文字" class="demo">
|
||||
<el-rate v-model="value2" show-text :texts="['极差', '差', '一般', '好', '极好']" />
|
||||
</page-main>
|
||||
<page-main title="只读" class="demo">
|
||||
<el-rate v-model="value3" disabled show-score text-color="#ff9900" score-template="{value}" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
@@ -30,3 +14,19 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="评分" />
|
||||
<page-main title="基础用法" class="demo">
|
||||
<el-rate v-model="value1" />
|
||||
</page-main>
|
||||
<page-main title="辅助文字" class="demo">
|
||||
<el-rate v-model="value2" show-text :texts="['极差', '差', '一般', '好', '极好']" />
|
||||
</page-main>
|
||||
<page-main title="只读" class="demo">
|
||||
<el-rate v-model="value3" disabled show-score text-color="#ff9900" score-template="{value}" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,34 @@
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options1: [
|
||||
{ value: '选项1', label: '黄金糕' },
|
||||
{ value: '选项2', label: '双皮奶' },
|
||||
{ value: '选项3', label: '蚵仔煎' },
|
||||
{ value: '选项4', label: '龙须面' },
|
||||
{ value: '选项5', label: '北京烤鸭' }
|
||||
],
|
||||
value1: '',
|
||||
options2: [
|
||||
{ value: '选项1', label: '黄金糕' },
|
||||
{ value: '选项2', label: '双皮奶', disabled: true },
|
||||
{ value: '选项3', label: '蚵仔煎' },
|
||||
{ value: '选项4', label: '龙须面' },
|
||||
{ value: '选项5', label: '北京烤鸭' }
|
||||
],
|
||||
value2: '',
|
||||
value3: []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -34,34 +65,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options1: [
|
||||
{ value: '选项1', label: '黄金糕' },
|
||||
{ value: '选项2', label: '双皮奶' },
|
||||
{ value: '选项3', label: '蚵仔煎' },
|
||||
{ value: '选项4', label: '龙须面' },
|
||||
{ value: '选项5', label: '北京烤鸭' }
|
||||
],
|
||||
value1: '',
|
||||
options2: [
|
||||
{ value: '选项1', label: '黄金糕' },
|
||||
{ value: '选项2', label: '双皮奶', disabled: true },
|
||||
{ value: '选项3', label: '蚵仔煎' },
|
||||
{ value: '选项4', label: '龙须面' },
|
||||
{ value: '选项5', label: '北京烤鸭' }
|
||||
],
|
||||
value2: '',
|
||||
value3: []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,31 @@
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value1: 0,
|
||||
value2: 50,
|
||||
value3: 36,
|
||||
value4: 48,
|
||||
value5: 42,
|
||||
value6: 0,
|
||||
value7: 0,
|
||||
value8: [4, 8],
|
||||
value9: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatTooltip(val) {
|
||||
return val / 100
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
@@ -31,31 +59,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value1: 0,
|
||||
value2: 50,
|
||||
value3: 36,
|
||||
value4: 48,
|
||||
value5: 42,
|
||||
value6: 0,
|
||||
value7: 0,
|
||||
value8: [4, 8],
|
||||
value9: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatTooltip(val) {
|
||||
return val / 100
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="开关" />
|
||||
<page-main title="基础用法" class="demo">
|
||||
<el-switch v-model="value" active-color="#13ce66" inactive-color="#ff4949" />
|
||||
</page-main>
|
||||
<page-main title="文字描述" class="demo">
|
||||
<el-switch v-model="value1" active-text="按月付费" inactive-text="按年付费" />
|
||||
</page-main>
|
||||
<page-main title="禁用状态" class="demo">
|
||||
<el-switch v-model="value2" disabled style="margin-right: 10px;" />
|
||||
<el-switch v-model="value3" disabled />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
@@ -32,3 +15,20 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="开关" />
|
||||
<page-main title="基础用法" class="demo">
|
||||
<el-switch v-model="value" active-color="#13ce66" inactive-color="#ff4949" />
|
||||
</page-main>
|
||||
<page-main title="文字描述" class="demo">
|
||||
<el-switch v-model="value1" active-text="按月付费" inactive-text="按年付费" />
|
||||
</page-main>
|
||||
<page-main title="禁用状态" class="demo">
|
||||
<el-switch v-model="value2" disabled style="margin-right: 10px;" />
|
||||
<el-switch v-model="value3" disabled />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="时间选择器" />
|
||||
<page-main title="固定时间点" class="demo">
|
||||
<el-time-select v-model="value" start="08:30" step="00:15" end="18:30" placeholder="选择时间" />
|
||||
</page-main>
|
||||
<page-main title="任意时间点" class="demo">
|
||||
<el-time-picker v-model="value1" :disabled-hours="disabledHours" :disabled-minutes="disabledMinutes" :disabled-seconds="disabledSeconds" placeholder="任意时间点" />
|
||||
</page-main>
|
||||
<page-main title="固定时间范围" class="demo">
|
||||
<el-time-select v-model="startTime" placeholder="起始时间" start="08:30" step="00:15" end="18:30" style="margin-right: 10px;" />
|
||||
<el-time-select v-model="endTime" placeholder="结束时间" start="08:30" step="00:15" end="18:30" :min-time="startTime" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Alert from './components/alert.vue'
|
||||
|
||||
@@ -58,3 +41,20 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Alert />
|
||||
<page-header title="时间选择器" />
|
||||
<page-main title="固定时间点" class="demo">
|
||||
<el-time-select v-model="value" start="08:30" step="00:15" end="18:30" placeholder="选择时间" />
|
||||
</page-main>
|
||||
<page-main title="任意时间点" class="demo">
|
||||
<el-time-picker v-model="value1" :disabled-hours="disabledHours" :disabled-minutes="disabledMinutes" :disabled-seconds="disabledSeconds" placeholder="任意时间点" />
|
||||
</page-main>
|
||||
<page-main title="固定时间范围" class="demo">
|
||||
<el-time-select v-model="startTime" placeholder="起始时间" start="08:30" step="00:15" end="18:30" style="margin-right: 10px;" />
|
||||
<el-time-select v-model="endTime" placeholder="结束时间" start="08:30" step="00:15" end="18:30" :min-time="startTime" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
region: '',
|
||||
date1: '',
|
||||
date2: '',
|
||||
delivery: false,
|
||||
type: [],
|
||||
resource: '',
|
||||
desc: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="固定底部操作栏" content="避免因页面过长导致操作按钮需要滚动到页面底部才能操作,例如表单页">
|
||||
@@ -134,22 +153,3 @@
|
||||
</fixed-action-bar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
region: '',
|
||||
date1: '',
|
||||
date2: '',
|
||||
delivery: false,
|
||||
type: [],
|
||||
resource: '',
|
||||
desc: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,22 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="省市区联动" content="CascaderArea" />
|
||||
<page-main>
|
||||
<cascader-area v-model="area" />
|
||||
</page-main>
|
||||
<page-main title="表单验证">
|
||||
<el-form ref="ruleForm" :model="ruleForm" :rules="rules">
|
||||
<el-form-item label="地区" prop="area">
|
||||
<cascader-area v-model="ruleForm.area" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm">提交</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ComponentExampleArea',
|
||||
@@ -48,6 +29,21 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// scss
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="省市区联动" content="CascaderArea" />
|
||||
<page-main>
|
||||
<cascader-area v-model="area" />
|
||||
</page-main>
|
||||
<page-main title="表单验证">
|
||||
<el-form ref="ruleForm" :model="ruleForm" :rules="rules">
|
||||
<el-form-item label="地区" prop="area">
|
||||
<cascader-area v-model="ruleForm.area" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm">提交</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,36 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="批量操作栏">
|
||||
<template #content>
|
||||
<p>BatchActionBar</p>
|
||||
<p style="margin-bottom: 0;">该组件需要和 ElTable 搭配使用</p>
|
||||
</template>
|
||||
</page-header>
|
||||
<page-main>
|
||||
<batch-action-bar :data="dataList" :selection-data="selectionDataList" @check-all="$refs.table.toggleAllSelection()" @check-null="$refs.table.clearSelection()">
|
||||
<el-button size="default">单个批量操作按钮</el-button>
|
||||
<el-button-group>
|
||||
<el-button size="default">批量操作按钮组1</el-button>
|
||||
<el-button size="default">批量操作按钮组2</el-button>
|
||||
</el-button-group>
|
||||
</batch-action-bar>
|
||||
<el-table ref="table" :data="dataList" border stripe highlight-current-row @selection-change="selectionDataList = $event">
|
||||
<el-table-column type="selection" width="40" />
|
||||
<el-table-column prop="date" label="日期" width="180" />
|
||||
<el-table-column prop="name" label="姓名" width="180" />
|
||||
<el-table-column prop="address" label="地址" />
|
||||
</el-table>
|
||||
<batch-action-bar :data="dataList" :selection-data="selectionDataList" @check-all="$refs.table.toggleAllSelection()" @check-null="$refs.table.clearSelection()">
|
||||
<el-button size="default">单个批量操作按钮</el-button>
|
||||
<el-button-group>
|
||||
<el-button size="default">批量操作按钮组1</el-button>
|
||||
<el-button size="default">批量操作按钮组2</el-button>
|
||||
</el-button-group>
|
||||
</batch-action-bar>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ComponentExampleBatchactionbar',
|
||||
@@ -68,6 +35,35 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// scss
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="批量操作栏">
|
||||
<template #content>
|
||||
<p>BatchActionBar</p>
|
||||
<p style="margin-bottom: 0;">该组件需要和 ElTable 搭配使用</p>
|
||||
</template>
|
||||
</page-header>
|
||||
<page-main>
|
||||
<batch-action-bar :data="dataList" :selection-data="selectionDataList" @check-all="$refs.table.toggleAllSelection()" @check-null="$refs.table.clearSelection()">
|
||||
<el-button size="default">单个批量操作按钮</el-button>
|
||||
<el-button-group>
|
||||
<el-button size="default">批量操作按钮组1</el-button>
|
||||
<el-button size="default">批量操作按钮组2</el-button>
|
||||
</el-button-group>
|
||||
</batch-action-bar>
|
||||
<el-table ref="table" :data="dataList" border stripe highlight-current-row @selection-change="selectionDataList = $event">
|
||||
<el-table-column type="selection" width="40" />
|
||||
<el-table-column prop="date" label="日期" width="180" />
|
||||
<el-table-column prop="name" label="姓名" width="180" />
|
||||
<el-table-column prop="address" label="地址" />
|
||||
</el-table>
|
||||
<batch-action-bar :data="dataList" :selection-data="selectionDataList" @check-all="$refs.table.toggleAllSelection()" @check-null="$refs.table.clearSelection()">
|
||||
<el-button size="default">单个批量操作按钮</el-button>
|
||||
<el-button-group>
|
||||
<el-button size="default">批量操作按钮组1</el-button>
|
||||
<el-button size="default">批量操作按钮组2</el-button>
|
||||
</el-button-group>
|
||||
</batch-action-bar>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-main title="富文本编辑器">
|
||||
<editor v-model="content1" />
|
||||
<div class="preview" v-html="content1" />
|
||||
</page-main>
|
||||
<page-main title="markdown 编辑器">
|
||||
<mavon-editor v-model="content2" style="z-index: 9;" />
|
||||
<div class="preview" v-html="mdContent2" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { mavonEditor } from 'mavon-editor'
|
||||
import 'mavon-editor/dist/css/index.css'
|
||||
@@ -24,6 +11,19 @@ const mdContent2 = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-main title="富文本编辑器">
|
||||
<editor v-model="content1" />
|
||||
<div class="preview" v-html="content1" />
|
||||
</page-main>
|
||||
<page-main title="markdown 编辑器">
|
||||
<mavon-editor v-model="content2" style="z-index: 9;" />
|
||||
<div class="preview" v-html="mdContent2" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.preview {
|
||||
margin-top: 10px;
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="图片预览" content="ImagePreview" />
|
||||
<page-main>
|
||||
<div>
|
||||
<image-preview :src="`https://hooray.${locationOrigin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/logo.png`" :width="200" />
|
||||
</div>
|
||||
</page-main>
|
||||
<page-main title="图片加载失败时">
|
||||
<div>
|
||||
<image-preview src="http://www.baidu.com" width="100px" height="100px" />
|
||||
</div>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {},
|
||||
@@ -29,6 +13,18 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// scss
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="图片预览" content="ImagePreview" />
|
||||
<page-main>
|
||||
<div>
|
||||
<image-preview :src="`https://hooray.${locationOrigin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/logo.png`" :width="200" />
|
||||
</div>
|
||||
</page-main>
|
||||
<page-main title="图片加载失败时">
|
||||
<div>
|
||||
<image-preview src="http://www.baidu.com" width="100px" height="100px" />
|
||||
</div>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
name: '',
|
||||
department_id: '',
|
||||
department_job_id: '',
|
||||
role_id: '',
|
||||
check1: true,
|
||||
check2: false
|
||||
},
|
||||
searchMore: false,
|
||||
searchMore2: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="搜索面板" content="SearchBar" />
|
||||
@@ -111,22 +130,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
name: '',
|
||||
department_id: '',
|
||||
department_job_id: '',
|
||||
role_id: '',
|
||||
check1: true,
|
||||
check2: false
|
||||
},
|
||||
searchMore: false,
|
||||
searchMore2: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
flip: '',
|
||||
rotate: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="SVG Icon" content="除了使用 Element Plus 提供的图标外,你还可以使用自己的 SVG 图标" />
|
||||
@@ -29,17 +40,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
flip: '',
|
||||
rotate: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.example-icon {
|
||||
font-size: 48px;
|
||||
|
||||
@@ -1,25 +1,3 @@
|
||||
<template>
|
||||
<div class="absolute-container">
|
||||
<page-header title="表格高度自适应">
|
||||
<template #content>
|
||||
<p>TableHeightAdaption</p>
|
||||
<p style="margin-bottom: 0;">该组件必须包裹 ElTable 使用,并且需要对上级元素设置高度后才会生效</p>
|
||||
</template>
|
||||
</page-header>
|
||||
<page-main>
|
||||
<TableHeightAdaption>
|
||||
<el-table :data="dataList" border stripe highlight-current-row>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column prop="date" label="日期" width="180" />
|
||||
<el-table-column prop="name" label="姓名" width="180" />
|
||||
<el-table-column prop="address" label="地址" />
|
||||
</el-table>
|
||||
</TableHeightAdaption>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ComponentExampleTableHeightAdaption',
|
||||
@@ -133,6 +111,28 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="absolute-container">
|
||||
<page-header title="表格高度自适应">
|
||||
<template #content>
|
||||
<p>TableHeightAdaption</p>
|
||||
<p style="margin-bottom: 0;">该组件必须包裹 ElTable 使用,并且需要对上级元素设置高度后才会生效</p>
|
||||
</template>
|
||||
</page-header>
|
||||
<page-main>
|
||||
<TableHeightAdaption>
|
||||
<el-table :data="dataList" border stripe highlight-current-row>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column prop="date" label="日期" width="180" />
|
||||
<el-table-column prop="name" label="姓名" width="180" />
|
||||
<el-table-column prop="address" label="地址" />
|
||||
</el-table>
|
||||
</TableHeightAdaption>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.absolute-container {
|
||||
position: absolute;
|
||||
|
||||
@@ -1,18 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="上传" content="ImageUpload / ImagesUpload / FileUpload" />
|
||||
<page-main title="单图上传">
|
||||
<image-upload v-model:url="image" action="http://scrm.1daas.com/api/upload/upload" name="image" :width="250" :height="150" :data="{'token':'TKE615916022101558'}" @on-success="handleSuccess1" />
|
||||
</page-main>
|
||||
<page-main title="多图上传(默认最多3张)">
|
||||
<images-upload v-model:url="images" action="http://scrm.1daas.com/api/upload/upload" name="image" :data="{'token':'TKE615916022101558'}" @on-success="handleSuccess2" />
|
||||
</page-main>
|
||||
<page-main title="文件上传(默认最多3个)">
|
||||
<file-upload :files="files" action="http://scrm.1daas.com/api/upload/upload" name="image" :data="{'token':'TKE615916022101558'}" @on-success="handleSuccess3" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
@@ -65,3 +50,18 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="上传" content="ImageUpload / ImagesUpload / FileUpload" />
|
||||
<page-main title="单图上传">
|
||||
<image-upload v-model:url="image" action="http://scrm.1daas.com/api/upload/upload" name="image" :width="250" :height="150" :data="{'token':'TKE615916022101558'}" @on-success="handleSuccess1" />
|
||||
</page-main>
|
||||
<page-main title="多图上传(默认最多3张)">
|
||||
<images-upload v-model:url="images" action="http://scrm.1daas.com/api/upload/upload" name="image" :data="{'token':'TKE615916022101558'}" @on-success="handleSuccess2" />
|
||||
</page-main>
|
||||
<page-main title="文件上传(默认最多3个)">
|
||||
<file-upload :files="files" action="http://scrm.1daas.com/api/upload/upload" name="image" :data="{'token':'TKE615916022101558'}" @on-success="handleSuccess3" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
+46
-46
@@ -1,3 +1,49 @@
|
||||
<script setup>
|
||||
const locationOrigin = location.origin
|
||||
|
||||
function open(url) {
|
||||
window.open(url, 'top')
|
||||
}
|
||||
|
||||
const fantasticTemplateInfo = ref({
|
||||
feature: [
|
||||
'默认集成 vue-router 和 pinia',
|
||||
'全局 SCSS 资源引入',
|
||||
'全局组件自动注册',
|
||||
'支持 SVG 图标,CSS 精灵图自动合成',
|
||||
'支持 mock 数据,可摆脱后端束缚独立开发',
|
||||
'支持 gzip / brotli 优化项目体积,提高加载速度',
|
||||
'结合 IDE 插件、ESlint 、stylelint 、Git 钩子,轻松实现团队代码规范'
|
||||
]
|
||||
})
|
||||
|
||||
const fantasticAdminInfo = ref({
|
||||
imageVisible: false,
|
||||
index: 0,
|
||||
data: [
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview1.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview2.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview3.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview4.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview5.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview6.png`
|
||||
]
|
||||
})
|
||||
|
||||
const oneStepAdminInfo = ref({
|
||||
imageVisible: false,
|
||||
index: 0,
|
||||
data: [
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview1.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview2.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview3.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview4.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview5.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview6.png`
|
||||
]
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="欢迎使用 Fantastic-admin(基础版)">
|
||||
@@ -93,52 +139,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const locationOrigin = location.origin
|
||||
|
||||
function open(url) {
|
||||
window.open(url, 'top')
|
||||
}
|
||||
|
||||
const fantasticTemplateInfo = ref({
|
||||
feature: [
|
||||
'默认集成 vue-router 和 pinia',
|
||||
'全局 SCSS 资源引入',
|
||||
'全局组件自动注册',
|
||||
'支持 SVG 图标,CSS 精灵图自动合成',
|
||||
'支持 mock 数据,可摆脱后端束缚独立开发',
|
||||
'支持 gzip / brotli 优化项目体积,提高加载速度',
|
||||
'结合 IDE 插件、ESlint 、stylelint 、Git 钩子,轻松实现团队代码规范'
|
||||
]
|
||||
})
|
||||
|
||||
const fantasticAdminInfo = ref({
|
||||
imageVisible: false,
|
||||
index: 0,
|
||||
data: [
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview1.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview2.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview3.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview4.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview5.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/fantastic-admin/preview6.png`
|
||||
]
|
||||
})
|
||||
|
||||
const oneStepAdminInfo = ref({
|
||||
imageVisible: false,
|
||||
index: 0,
|
||||
data: [
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview1.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview2.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview3.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview4.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview5.png`,
|
||||
`https://hooray.${location.origin.includes('gitee') ? 'gitee' : 'github'}.io/one-step-admin/preview6.png`
|
||||
]
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text-emphasis {
|
||||
/* stylelint-disable-next-line property-no-vendor-prefix */
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<script setup name="TabExampleNested1">
|
||||
import { useKeepAliveStore } from '@/store/modules/keepAlive'
|
||||
const keepAliveStore = useKeepAliveStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-main>
|
||||
@@ -10,8 +15,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="TabExampleNested1">
|
||||
import { useKeepAliveStore } from '@/store/modules/keepAlive'
|
||||
const keepAliveStore = useKeepAliveStore()
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<script setup name="TabExampleNested2">
|
||||
import { useKeepAliveStore } from '@/store/modules/keepAlive'
|
||||
const keepAliveStore = useKeepAliveStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-main>
|
||||
@@ -10,8 +15,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="TabExampleNested2">
|
||||
import { useKeepAliveStore } from '@/store/modules/keepAlive'
|
||||
const keepAliveStore = useKeepAliveStore()
|
||||
</script>
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-main>
|
||||
<div>层级 1-1-1</div>
|
||||
<el-input v-model="val" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TabExampleNestedTest',
|
||||
@@ -17,3 +8,12 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-main>
|
||||
<div>层级 1-1-1</div>
|
||||
<el-input v-model="val" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-main>
|
||||
<div>层级 1-1-2</div>
|
||||
<el-input v-model="val" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TabExampleNestedTest2',
|
||||
@@ -17,3 +8,12 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-main>
|
||||
<div>层级 1-1-2</div>
|
||||
<el-input v-model="val" />
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,21 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="页面缓存" content="除了可以在路由里配置页面是否需要缓存外,你也可以不使用框架提供的方法,而是在页面里自行实现,该方法目前仅支持在 Options API 中实现。" />
|
||||
<page-main>
|
||||
<div class="block">
|
||||
<el-switch v-model="openKeepAlive" active-text="开启缓存" inactive-text="关闭缓存" />
|
||||
</div>
|
||||
<div class="block">
|
||||
<el-input-number v-model="num" />
|
||||
</div>
|
||||
<div class="block">
|
||||
<el-button @click="go(1)">进入同级路由页面</el-button>
|
||||
<el-button @click="go(2)">进入下级路由页面</el-button>
|
||||
</div>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="KeepAliveExamplePage">
|
||||
import { onBeforeRouteLeave } from 'vue-router'
|
||||
|
||||
@@ -54,6 +36,24 @@ onBeforeRouteLeave((to, from) => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="页面缓存" content="除了可以在路由里配置页面是否需要缓存外,你也可以不使用框架提供的方法,而是在页面里自行实现,该方法目前仅支持在 Options API 中实现。" />
|
||||
<page-main>
|
||||
<div class="block">
|
||||
<el-switch v-model="openKeepAlive" active-text="开启缓存" inactive-text="关闭缓存" />
|
||||
</div>
|
||||
<div class="block">
|
||||
<el-input-number v-model="num" />
|
||||
</div>
|
||||
<div class="block">
|
||||
<el-button @click="go(1)">进入同级路由页面</el-button>
|
||||
<el-button @click="go(2)">进入下级路由页面</el-button>
|
||||
</div>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.block {
|
||||
margin-bottom: 10px;
|
||||
|
||||
+86
-86
@@ -1,89 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-banner" />
|
||||
<div id="login-box">
|
||||
<div class="login-banner" />
|
||||
<el-form v-show="formType == 'login'" ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
|
||||
<div class="title-container">
|
||||
<h3 class="title">{{ title }}管理后台</h3>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item prop="account">
|
||||
<el-input ref="name" v-model="loginForm.account" placeholder="用户名" type="text" tabindex="1" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="user" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input ref="password" v-model="loginForm.password" :type="passwordType" placeholder="密码" tabindex="2" autocomplete="on" @keyup.enter="handleLogin">
|
||||
<template #prefix>
|
||||
<svg-icon name="password" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" @click="showPassword" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-bar">
|
||||
<el-checkbox v-model="loginForm.remember">记住我</el-checkbox>
|
||||
<el-button type="text" @click="formType = 'reset'">忘记密码</el-button>
|
||||
</div>
|
||||
<el-button :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleLogin">登 录</el-button>
|
||||
<div style="margin-top: 20px; margin-bottom: -10px; color: #666; font-size: 14px; text-align: center; font-weight: bold;">
|
||||
<span style="margin-right: 5px;">演示帐号一键登录:</span>
|
||||
<el-button type="danger" size="small" @click="testAccount('admin')">admin</el-button>
|
||||
<el-button type="danger" size="small" plain @click="testAccount('test')">test</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-form v-show="formType == 'reset'" ref="resetFormRef" :model="resetForm" :rules="resetRules" class="login-form" auto-complete="on" label-position="left">
|
||||
<div class="title-container">
|
||||
<h3 class="title">重置密码</h3>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item prop="account">
|
||||
<el-input ref="name" v-model="resetForm.account" placeholder="用户名" type="text" tabindex="1" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="user" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="captcha">
|
||||
<el-input ref="captcha" v-model="resetForm.captcha" placeholder="验证码" type="text" tabindex="2" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="captcha" />
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button>发送验证码</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="newPassword">
|
||||
<el-input ref="newPassword" v-model="resetForm.newPassword" :type="passwordType" placeholder="新密码" tabindex="3" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="password" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" @click="showPassword" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-row :gutter="15" style="padding-top: 20px;">
|
||||
<el-col :md="6">
|
||||
<el-button size="large" style="width: 100%;" @click="formType = 'login'">去登录</el-button>
|
||||
</el-col>
|
||||
<el-col :md="18">
|
||||
<el-button :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleFind">确 认</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
<Copyright v-if="settingsStore.copyright.enable" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Login">
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute(), router = useRouter()
|
||||
@@ -184,6 +98,92 @@ function testAccount(account) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-banner" />
|
||||
<div id="login-box">
|
||||
<div class="login-banner" />
|
||||
<el-form v-show="formType == 'login'" ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
|
||||
<div class="title-container">
|
||||
<h3 class="title">{{ title }}管理后台</h3>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item prop="account">
|
||||
<el-input ref="name" v-model="loginForm.account" placeholder="用户名" type="text" tabindex="1" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="user" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input ref="password" v-model="loginForm.password" :type="passwordType" placeholder="密码" tabindex="2" autocomplete="on" @keyup.enter="handleLogin">
|
||||
<template #prefix>
|
||||
<svg-icon name="password" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" @click="showPassword" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-bar">
|
||||
<el-checkbox v-model="loginForm.remember">记住我</el-checkbox>
|
||||
<el-button type="text" @click="formType = 'reset'">忘记密码</el-button>
|
||||
</div>
|
||||
<el-button :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleLogin">登 录</el-button>
|
||||
<div style="margin-top: 20px; margin-bottom: -10px; color: #666; font-size: 14px; text-align: center; font-weight: bold;">
|
||||
<span style="margin-right: 5px;">演示帐号一键登录:</span>
|
||||
<el-button type="danger" size="small" @click="testAccount('admin')">admin</el-button>
|
||||
<el-button type="danger" size="small" plain @click="testAccount('test')">test</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-form v-show="formType == 'reset'" ref="resetFormRef" :model="resetForm" :rules="resetRules" class="login-form" auto-complete="on" label-position="left">
|
||||
<div class="title-container">
|
||||
<h3 class="title">重置密码</h3>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item prop="account">
|
||||
<el-input ref="name" v-model="resetForm.account" placeholder="用户名" type="text" tabindex="1" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="user" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="captcha">
|
||||
<el-input ref="captcha" v-model="resetForm.captcha" placeholder="验证码" type="text" tabindex="2" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="captcha" />
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button>发送验证码</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="newPassword">
|
||||
<el-input ref="newPassword" v-model="resetForm.newPassword" :type="passwordType" placeholder="新密码" tabindex="3" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="password" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" @click="showPassword" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-row :gutter="15" style="padding-top: 20px;">
|
||||
<el-col :md="6">
|
||||
<el-button size="large" style="width: 100%;" @click="formType = 'login'">去登录</el-button>
|
||||
</el-col>
|
||||
<el-col :md="18">
|
||||
<el-button :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleFind">确 认</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
<Copyright v-if="settingsStore.copyright.enable" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
[data-mode="mobile"] {
|
||||
#login-box {
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="Mock" content="通过拦截 Ajax 请求,返回模拟的响应数据,可以让前端工程师独立于后端进行开发,本演示站的登录和权限获取就是通过 mock 实现的。更多 Mock 语法规则请查询官方文档">
|
||||
<el-button icon="el-icon-link" @click="open('http://mockjs.com/')">Mock.js 官网</el-button>
|
||||
</page-header>
|
||||
<page-main>
|
||||
<el-button @click="getPermission">测试:获取用户权限</el-button>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
@@ -29,3 +18,14 @@ function open(url) {
|
||||
window.open(url, 'top')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="Mock" content="通过拦截 Ajax 请求,返回模拟的响应数据,可以让前端工程师独立于后端进行开发,本演示站的登录和权限获取就是通过 mock 实现的。更多 Mock 语法规则请查询官方文档">
|
||||
<el-button icon="el-icon-link" @click="open('http://mockjs.com/')">Mock.js 官网</el-button>
|
||||
</page-header>
|
||||
<page-main>
|
||||
<el-button @click="getPermission">测试:获取用户权限</el-button>
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,42 @@
|
||||
<script setup>
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore()
|
||||
|
||||
function accountChange(val) {
|
||||
proxy.$loading({
|
||||
lock: true,
|
||||
text: '帐号切换中',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
userStore.login({
|
||||
account: val,
|
||||
password: ''
|
||||
}).then(() => {
|
||||
setTimeout(() => {
|
||||
location.reload()
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
function permissionCheck(permissions) {
|
||||
if (proxy.$auth(permissions)) {
|
||||
proxy.$message.success('校验通过')
|
||||
} else {
|
||||
proxy.$message.error('校验不通过')
|
||||
}
|
||||
}
|
||||
function permissionCheck2(permissions) {
|
||||
if (proxy.$authAll(permissions)) {
|
||||
proxy.$message.success('校验通过')
|
||||
} else {
|
||||
proxy.$message.error('校验不通过')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="权限验证" />
|
||||
@@ -68,42 +107,3 @@
|
||||
</page-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore()
|
||||
|
||||
function accountChange(val) {
|
||||
proxy.$loading({
|
||||
lock: true,
|
||||
text: '帐号切换中',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
userStore.login({
|
||||
account: val,
|
||||
password: ''
|
||||
}).then(() => {
|
||||
setTimeout(() => {
|
||||
location.reload()
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
function permissionCheck(permissions) {
|
||||
if (proxy.$auth(permissions)) {
|
||||
proxy.$message.success('校验通过')
|
||||
} else {
|
||||
proxy.$message.error('校验不通过')
|
||||
}
|
||||
}
|
||||
function permissionCheck2(permissions) {
|
||||
if (proxy.$authAll(permissions)) {
|
||||
proxy.$message.success('校验通过')
|
||||
} else {
|
||||
proxy.$message.error('校验不通过')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,29 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="修改密码" content="定期修改密码可以提高帐号安全性噢~" />
|
||||
<page-main>
|
||||
<el-row>
|
||||
<el-col :md="24" :lg="12">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="原密码" prop="password">
|
||||
<el-input v-model="form.password" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newpassword">
|
||||
<el-input v-model="form.newpassword" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码" prop="checkpassword">
|
||||
<el-input v-model="form.checkpassword" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</page-main>
|
||||
<fixed-action-bar>
|
||||
<el-button type="primary" size="large" @click="onSubmit">提交</el-button>
|
||||
</fixed-action-bar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="PersonalEditPassword">
|
||||
const route = useRoute(), router = useRouter()
|
||||
const { proxy } = getCurrentInstance()
|
||||
@@ -80,3 +54,29 @@ function onSubmit() {
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="修改密码" content="定期修改密码可以提高帐号安全性噢~" />
|
||||
<page-main>
|
||||
<el-row>
|
||||
<el-col :md="24" :lg="12">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="原密码" prop="password">
|
||||
<el-input v-model="form.password" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newpassword">
|
||||
<el-input v-model="form.newpassword" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码" prop="checkpassword">
|
||||
<el-input v-model="form.checkpassword" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</page-main>
|
||||
<fixed-action-bar>
|
||||
<el-button type="primary" size="large" @click="onSubmit">提交</el-button>
|
||||
</fixed-action-bar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
<script setup name="PersonalSetting">
|
||||
const router = useRouter()
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const form = ref({
|
||||
headimg: '',
|
||||
mobile: '',
|
||||
name: '',
|
||||
qq: '',
|
||||
wechat: ''
|
||||
})
|
||||
|
||||
function handleSuccess(res) {
|
||||
if (res.error == '') {
|
||||
form.value.headimg = res.data.path
|
||||
} else {
|
||||
proxy.$message.warning(res.error)
|
||||
}
|
||||
}
|
||||
function editPassword() {
|
||||
router.push({
|
||||
name: 'personalEditPassword'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- 页面:Setting -->
|
||||
@@ -67,32 +93,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="PersonalSetting">
|
||||
const router = useRouter()
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const form = ref({
|
||||
headimg: '',
|
||||
mobile: '',
|
||||
name: '',
|
||||
qq: '',
|
||||
wechat: ''
|
||||
})
|
||||
|
||||
function handleSuccess(res) {
|
||||
if (res.error == '') {
|
||||
form.value.headimg = res.data.path
|
||||
} else {
|
||||
proxy.$message.warning(res.error)
|
||||
}
|
||||
}
|
||||
function editPassword() {
|
||||
router.push({
|
||||
name: 'personalEditPassword'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tabs) {
|
||||
.el-tabs__header .el-tabs__nav {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup>
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(() => {
|
||||
router.go(-1)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.$router.go(-1)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user