Merge pull request #42 from xiaoxian521/refactor/home

Refactor/home
This commit is contained in:
啝裳 2021-09-21 19:18:47 +08:00 committed by GitHub
commit 15e751dee8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 646 additions and 176 deletions

View File

@ -0,0 +1,36 @@
import { App } from "vue";
import reBar from "./src/Bar.vue";
import reGithub from "./src/Github.vue";
import reInfinite from "./src/Infinite.vue";
import reLine from "./src/Line.vue";
import rePie from "./src/Pie.vue";
export const ReBar = Object.assign(reBar, {
install(app: App) {
app.component(reBar.name, reBar);
}
});
export const ReGithub = Object.assign(reGithub, {
install(app: App) {
app.component(reGithub.name, reGithub);
}
});
export const ReInfinite = Object.assign(reInfinite, {
install(app: App) {
app.component(reInfinite.name, reInfinite);
}
});
export const ReLine = Object.assign(reLine, {
install(app: App) {
app.component(reLine.name, reLine);
}
});
export const RePie = Object.assign(rePie, {
install(app: App) {
app.component(rePie.name, rePie);
}
});

View File

@ -0,0 +1,96 @@
<script lang="ts">
export default {
name: "Bar"
};
</script>
<script setup lang="ts">
import { ECharts } from "echarts";
import echarts from "/@/plugins/echarts";
import { onBeforeMount, onMounted, nextTick } from "vue";
import { useEventListener, tryOnUnmounted, useTimeoutFn } from "@vueuse/core";
let echartInstance: ECharts;
function initechartInstance() {
const echartDom = document.querySelector(".bar");
if (!echartDom) return;
// @ts-ignore
echartInstance = echarts.init(echartDom);
echartInstance.clear(); //
echartInstance.setOption({
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
bottom: "20%",
height: "68%",
containLabel: true
},
xAxis: [
{
type: "category",
axisTick: {
alignWithLabel: true
},
axisLabel: {
interval: 0
// width: "70",
// overflow: "truncate"
},
data: ["open_issues", "forks", "watchers", "star"]
}
],
yAxis: [
{
type: "value"
}
],
series: [
{
name: "GitHub信息",
type: "bar",
data: [3, 204, 1079, 1079]
}
]
});
}
onBeforeMount(() => {
nextTick(() => {
initechartInstance();
});
});
onMounted(() => {
nextTick(() => {
useEventListener("resize", () => {
if (!echartInstance) return;
useTimeoutFn(() => {
echartInstance.resize();
}, 180);
});
});
});
tryOnUnmounted(() => {
if (!echartInstance) return;
echartInstance.dispose();
echartInstance = null;
});
</script>
<template>
<div class="bar"></div>
</template>
<style scoped>
.bar {
width: 100%;
height: 35vh;
}
</style>

View File

@ -0,0 +1,93 @@
<template>
<el-descriptions
class="margin-top"
direction="vertical"
:column="3"
size="medium"
border
>
<el-descriptions-item>
<template #label>
<i class="el-icon-user"></i>
用户名
</template>
xiaoxian
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<i class="el-icon-mobile-phone"></i>
手机号
</template>
123456789
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<i class="el-icon-location-outline"></i>
居住地
</template>
上海
</el-descriptions-item>
</el-descriptions>
<el-descriptions
class="margin-top"
direction="vertical"
:column="2"
size="medium"
border
>
<el-descriptions-item>
<template #label>
<i class="el-icon-tickets"></i>
标签
</template>
<el-tag
v-for="item in lists"
:key="item.label"
:type="item.type"
size="mini"
effect="dark"
>
{{ item.label }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<i class="el-icon-office-building"></i>
联系地址
</template>
上海市徐汇区
</el-descriptions-item>
</el-descriptions>
<el-descriptions
class="margin-top"
direction="vertical"
:column="1"
size="medium"
border
>
<el-descriptions-item>
<template #label>
<i class="el-icon-notebook-1"></i>
留言
</template>
好好学习天天向上
</el-descriptions-item>
</el-descriptions>
</template>
<script setup lang="ts">
import { ref } from "vue";
const lists = ref<ForDataType<undefined>>([
{ type: "", label: "善良" },
{ type: "success", label: "好学" },
{ type: "info", label: "幽默" },
{ type: "danger", label: "旅游" },
{ type: "warning", label: "追剧" }
]);
</script>
<style scoped>
.el-tag--mini {
margin-right: 10px !important;
}
</style>

View File

@ -0,0 +1,134 @@
<script setup lang="ts">
import { ref, reactive } from "vue";
import { templateRef } from "@vueuse/core";
import SeamlessScroll from "/@/components/ReSeamlessScroll";
const scroll = templateRef<ElRef | null>("scroll", null);
let listData = ref<ForDataType<undefined>>([
{
date: "2021-09-01",
name: "vue-pure-admin",
star: "1000"
},
{
date: "2021-09-02",
name: "vue-pure-admin",
star: "1100"
},
{
date: "2021-09-03",
name: "vue-pure-admin",
star: "1200"
},
{
date: "2021-09-04",
name: "vue-pure-admin",
star: "1300"
},
{
date: "2021-09-05",
name: "vue-pure-admin",
star: "1400"
},
{
date: "2021-09-06",
name: "vue-pure-admin",
star: "1500"
},
{
date: "2021-09-07",
name: "vue-pure-admin",
star: "1600"
},
{
date: "2021-09-08",
name: "vue-pure-admin",
star: "1700"
},
{
date: "2021-09-09",
name: "vue-pure-admin",
star: "1800"
},
{
date: "2021-09-10",
name: "vue-pure-admin",
star: "1900"
}
]);
let classOption = reactive({
direction: "top"
});
</script>
<template>
<div class="infinite">
<ul class="top">
<li>更新日期</li>
<li>项目名称</li>
<li>Star数量</li>
</ul>
<SeamlessScroll
ref="scroll"
:data="listData"
:class-option="classOption"
class="warp"
>
<ul class="item">
<li v-for="(item, index) in listData" :key="index">
<span v-text="item.date"></span>
<span v-text="item.name"></span>
<span v-text="item.star"></span>
</li>
</ul>
</SeamlessScroll>
</div>
</template>
<style lang="scss" scoped>
.infinite {
.top {
width: 95%;
height: 40px;
line-height: 40px;
display: flex;
margin: 0 auto;
font-size: 14px;
color: #909399;
font-weight: 400;
background: #fafafa;
li {
width: 34%;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.warp {
width: 95%;
height: 230px;
margin: 0 auto;
overflow: hidden;
li {
height: 30px;
line-height: 30px;
display: flex;
font-size: 15px;
}
span {
width: 34%;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
</style>

View File

@ -0,0 +1,84 @@
<script lang="ts">
export default {
name: "Line"
};
</script>
<script setup lang="ts">
import { ECharts } from "echarts";
import echarts from "/@/plugins/echarts";
import { onBeforeMount, onMounted, nextTick } from "vue";
import { useEventListener, tryOnUnmounted, useTimeoutFn } from "@vueuse/core";
let echartInstance: ECharts;
function initechartInstance() {
const echartDom = document.querySelector(".line");
if (!echartDom) return;
// @ts-ignore
echartInstance = echarts.init(echartDom);
echartInstance.clear(); //
echartInstance.setOption({
grid: {
bottom: "20%",
height: "68%",
containLabel: true
},
tooltip: {
trigger: "item"
},
xAxis: {
type: "category",
axisLabel: {
interval: 0
},
data: ["open_issues", "forks", "watchers", "star"]
},
yAxis: {
type: "value"
},
series: [
{
data: [3, 204, 1079, 1079],
type: "line",
areaStyle: {}
}
]
});
}
onBeforeMount(() => {
nextTick(() => {
initechartInstance();
});
});
onMounted(() => {
nextTick(() => {
useEventListener("resize", () => {
if (!echartInstance) return;
useTimeoutFn(() => {
echartInstance.resize();
}, 180);
});
});
});
tryOnUnmounted(() => {
if (!echartInstance) return;
echartInstance.dispose();
echartInstance = null;
});
</script>
<template>
<div class="line"></div>
</template>
<style scoped>
.line {
width: 100%;
height: 35vh;
}
</style>

View File

@ -0,0 +1,87 @@
<script lang="ts">
export default {
name: "Pie"
};
</script>
<script setup lang="ts">
import { ECharts } from "echarts";
import echarts from "/@/plugins/echarts";
import { onBeforeMount, onMounted, nextTick } from "vue";
import { useEventListener, tryOnUnmounted, useTimeoutFn } from "@vueuse/core";
let echartInstance: ECharts;
function initechartInstance() {
const echartDom = document.querySelector(".pie");
if (!echartDom) return;
// @ts-ignore
echartInstance = echarts.init(echartDom);
echartInstance.clear(); //
echartInstance.setOption({
tooltip: {
trigger: "item"
},
legend: {
orient: "vertical",
right: true
},
series: [
{
name: "Github信息",
type: "pie",
radius: "60%",
center: ["40%", "50%"],
data: [
{ value: 1079, name: "watchers" },
{ value: 1079, name: "star" },
{ value: 204, name: "forks" },
{ value: 3, name: "open_issues" }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)"
}
}
}
]
});
}
onBeforeMount(() => {
nextTick(() => {
initechartInstance();
});
});
onMounted(() => {
nextTick(() => {
useEventListener("resize", () => {
if (!echartInstance) return;
useTimeoutFn(() => {
echartInstance.resize();
}, 180);
});
});
});
tryOnUnmounted(() => {
if (!echartInstance) return;
echartInstance.dispose();
echartInstance = null;
});
</script>
<template>
<div class="pie"></div>
</template>
<style scoped>
.pie {
width: 100%;
height: 35vh;
}
</style>

View File

@ -1,27 +1,30 @@
import * as echarts from "echarts/core";
import { LineChart } from "echarts/charts";
import { PieChart, BarChart, LineChart } from "echarts/charts";
import { SVGRenderer } from "echarts/renderers";
import {
TitleComponent,
TooltipComponent,
GridComponent,
TitleComponent,
LegendComponent,
ToolboxComponent,
TooltipComponent,
DataZoomComponent,
VisualMapComponent
} from "echarts/components";
import { SVGRenderer } from "echarts/renderers";
const { use, registerTheme } = echarts;
use([
TitleComponent,
TooltipComponent,
GridComponent,
PieChart,
BarChart,
LineChart,
SVGRenderer,
GridComponent,
TitleComponent,
LegendComponent,
ToolboxComponent,
TooltipComponent,
DataZoomComponent,
VisualMapComponent
]);

View File

@ -1,5 +1,6 @@
import { App, Component } from "vue";
import {
ElTag,
ElAffix,
ElSkeleton,
ElBreadcrumb,
@ -30,10 +31,13 @@ import {
ElPagination,
ElAlert,
ElRadioButton,
ElRadioGroup
ElRadioGroup,
ElDescriptions,
ElDescriptionsItem
} from "element-plus";
const components = [
ElTag,
ElAffix,
ElSkeleton,
ElBreadcrumb,
@ -63,7 +67,9 @@ const components = [
ElPagination,
ElAlert,
ElRadioButton,
ElRadioGroup
ElRadioGroup,
ElDescriptions,
ElDescriptionsItem
];
const plugins = [ElLoading];

View File

@ -1,4 +1,5 @@
import { storageLocal } from "../../utils/storage";
import { storageLocal } from "/@/utils/storage";
import { deviceDetection } from "/@/utils/deviceDetection";
import { defineStore } from "pinia";
import { store } from "/@/store";
@ -19,7 +20,7 @@ export const useAppStore = defineStore({
: true,
withoutAnimation: false
},
device: "desktop"
device: deviceDetection() ? "mobile" : "desktop"
}),
getters: {
getSidebarStatus() {

View File

@ -1,20 +1,20 @@
<script setup lang="ts">
import { ref, computed, onMounted, nextTick } from "vue";
import { useEventListener, tryOnUnmounted, useTimeoutFn } from "@vueuse/core";
import { echartsJson } from "/@/api/mock";
import echarts from "/@/plugins/echarts";
import { ECharts } from "echarts";
import { ref, shallowRef, computed, onBeforeMount } from "vue";
import { useAppStoreHook } from "/@/store/modules/app";
import {
ReGithub,
ReInfinite,
RePie,
ReLine,
ReBar
} from "/@/components/ReCharts/index";
//线
let brokenLine: ECharts;
let date: Date = new Date();
const date: Date = new Date();
let loading = ref<boolean>(true);
const componentList = shallowRef<ForDataType<undefined>>([]);
setTimeout(() => {
loading.value = !loading.value;
nextTick(() => {
initbrokenLine();
});
}, 500);
let greetings = computed(() => {
@ -27,139 +27,59 @@ let greetings = computed(() => {
}
});
function initbrokenLine() {
const lineRefDom = document.getElementById("brokenLine");
if (!lineRefDom) return;
// @ts-ignore
brokenLine = echarts.init(lineRefDom);
brokenLine.clear(); //
echartsJson().then(({ info }) => {
brokenLine.setOption({
title: {
text: "上海 空气质量指数",
left: "1%"
onBeforeMount(() => {
if (useAppStoreHook().device === "mobile") {
componentList.value = [
{
width: "20em",
title: "GitHub饼图信息",
component: RePie
},
tooltip: {
trigger: "axis"
{
width: "20em",
title: "GitHub折线图信息",
component: ReLine
},
grid: {
left: "5%",
right: "15%",
bottom: "10%"
},
xAxis: {
data: info.map(function (item) {
return item[0];
})
},
yAxis: {},
toolbox: {
right: 10,
feature: {
saveAsImage: {}
}
},
dataZoom: [
{
startValue: "2014-06-01"
},
{
type: "inside"
}
],
visualMap: {
top: 50,
right: 10,
pieces: [
{
gt: 0,
lte: 50,
color: "#93CE07"
},
{
gt: 50,
lte: 100,
color: "#FBDB0F"
},
{
gt: 100,
lte: 150,
color: "#FC7D02"
},
{
gt: 150,
lte: 200,
color: "#FD0100"
},
{
gt: 200,
lte: 300,
color: "#AA069F"
},
{
gt: 300,
color: "#AC3B2A"
}
],
outOfRange: {
color: "#999"
}
},
series: {
name: "上海 空气质量指数",
type: "line",
data: info.map(function (item) {
return item[1];
}),
markLine: {
silent: true,
lineStyle: {
color: "#333"
},
data: [
{
yAxis: 50
},
{
yAxis: 100
},
{
yAxis: 150
},
{
yAxis: 200
},
{
yAxis: 300
}
]
}
{
width: "20em",
title: "GitHub柱状图信息",
component: ReBar
}
});
});
}
];
} else {
componentList.value = [
{
width: "43em",
title: "GitHub信息",
component: ReGithub
},
{
width: "43em",
title: "GitHub滚动信息",
component: ReInfinite
},
{
width: "28.28em",
title: "GitHub饼图信息",
component: RePie
},
{
width: "28.28em",
title: "GitHub折线图信息",
component: ReLine
},
{
width: "28.28em",
title: "GitHub柱状图信息",
component: ReBar
}
];
}
});
const openDepot = (): void => {
window.open("https://github.com/xiaoxian521/vue-pure-admin");
};
onMounted(() => {
nextTick(() => {
useEventListener("resize", () => {
if (!brokenLine) return;
useTimeoutFn(() => {
brokenLine.resize();
}, 180);
});
});
});
tryOnUnmounted(() => {
if (!brokenLine) return;
brokenLine.dispose();
brokenLine = null;
});
</script>
<template>
@ -176,32 +96,36 @@ tryOnUnmounted(() => {
</div>
</el-card>
<!-- 图表 -->
<el-space wrap>
<el-card class="box-card" style="width: 250px" v-for="i in 3" :key="i">
<template #header>
<div class="card-header">
<span>Card name</span>
<el-button class="button" type="text">Operation button</el-button>
<el-space class="space" wrap size="large">
<el-skeleton
v-for="(item, key) in componentList"
:key="key"
animated
:rows="7"
:loading="loading"
:class="$style.size"
:style="{ width: item.width }"
>
<template #default>
<div
:class="['echart-card', $style.size]"
:style="{ width: item.width }"
>
<h4>{{ item.title }}</h4>
<component :is="item.component"></component>
</div>
</template>
<div v-for="o in 4" :key="o" class="text item">
{{ "List item " + o }}
</div>
</el-card>
</el-space>
<!-- <el-card class="box-card">
<el-skeleton style="height: 50vh" :rows="8" :loading="loading" animated>
<template #default>
<div id="brokenLine"></div>
</template>
</el-skeleton>
</el-card> -->
</el-space>
</div>
</template>
<style module scoped>
.size {
height: 335px;
}
</style>
<style lang="scss" scoped>
.welcome {
width: 100%;
@ -233,14 +157,20 @@ tryOnUnmounted(() => {
}
}
.box-card {
width: 80vw;
margin: 10px auto;
position: relative;
.space {
display: flex;
justify-content: center;
align-items: center;
margin-left: 8px;
padding: 10px;
#brokenLine {
width: 100%;
height: 50vh;
.echart-card {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
h4 {
margin: 0;
padding: 20px;
}
}
}
}