mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-07 08:57:19 +08:00
perf: 首屏优化,减少 1.5MB
资源
This commit is contained in:
parent
a22bc8622e
commit
d2b1bd5b44
@ -32,13 +32,14 @@ export const include = [
|
|||||||
"lodash-unified",
|
"lodash-unified",
|
||||||
"@ctrl/tinycolor",
|
"@ctrl/tinycolor",
|
||||||
"china-area-data",
|
"china-area-data",
|
||||||
"@faker-js/faker",
|
|
||||||
"vue-json-pretty",
|
"vue-json-pretty",
|
||||||
"@logicflow/core",
|
"@logicflow/core",
|
||||||
"@pureadmin/utils",
|
"@pureadmin/utils",
|
||||||
|
"@wangeditor/editor",
|
||||||
"responsive-storage",
|
"responsive-storage",
|
||||||
"@howdyjs/mouse-menu",
|
"@howdyjs/mouse-menu",
|
||||||
"@logicflow/extension",
|
"@logicflow/extension",
|
||||||
|
"vue-virtual-scroller",
|
||||||
"element-resize-detector",
|
"element-resize-detector",
|
||||||
"@amap/amap-jsapi-loader",
|
"@amap/amap-jsapi-loader",
|
||||||
"el-table-infinite-scroll",
|
"el-table-infinite-scroll",
|
||||||
|
@ -86,7 +86,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "13.1.0",
|
"@commitlint/cli": "13.1.0",
|
||||||
"@commitlint/config-conventional": "13.1.0",
|
"@commitlint/config-conventional": "13.1.0",
|
||||||
"@faker-js/faker": "^7.5.0",
|
|
||||||
"@iconify-icons/carbon": "^1.2.8",
|
"@iconify-icons/carbon": "^1.2.8",
|
||||||
"@iconify-icons/ep": "^1.2.7",
|
"@iconify-icons/ep": "^1.2.7",
|
||||||
"@iconify-icons/fa": "^1.2.3",
|
"@iconify-icons/fa": "^1.2.3",
|
||||||
|
6199
pnpm-lock.yaml
generated
6199
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,12 @@
|
|||||||
import iconifyIconOffline from "./src/iconifyIconOffline";
|
import iconifyIconOffline from "./src/iconifyIconOffline";
|
||||||
import iconifyIconOnline from "./src/iconifyIconOnline";
|
import iconifyIconOnline from "./src/iconifyIconOnline";
|
||||||
import iconSelect from "./src/Select.vue";
|
|
||||||
import fontIcon from "./src/iconfont";
|
import fontIcon from "./src/iconfont";
|
||||||
|
|
||||||
/** 本地图标组件 */
|
/** 本地图标组件 */
|
||||||
const IconifyIconOffline = iconifyIconOffline;
|
const IconifyIconOffline = iconifyIconOffline;
|
||||||
/** 在线图标组件 */
|
/** 在线图标组件 */
|
||||||
const IconifyIconOnline = iconifyIconOnline;
|
const IconifyIconOnline = iconifyIconOnline;
|
||||||
/** 图标选择器组件 */
|
|
||||||
const IconSelect = iconSelect;
|
|
||||||
/** iconfont组件 */
|
/** iconfont组件 */
|
||||||
const FontIcon = fontIcon;
|
const FontIcon = fontIcon;
|
||||||
|
|
||||||
export { IconifyIconOffline, IconifyIconOnline, IconSelect, FontIcon };
|
export { IconifyIconOffline, IconifyIconOnline, FontIcon };
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { cloneDeep } from "lodash-unified";
|
import { cloneDeep } from "lodash-unified";
|
||||||
import { ref, computed, CSSProperties, toRef, watch } from "vue";
|
|
||||||
import { IconJson } from "@/components/ReIcon/data";
|
import { IconJson } from "@/components/ReIcon/data";
|
||||||
|
import { ref, computed, CSSProperties, toRef, watch } from "vue";
|
||||||
type ParameterCSSProperties = (item?: string) => CSSProperties | undefined;
|
type ParameterCSSProperties = (item?: string) => CSSProperties | undefined;
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
|
@ -42,7 +42,6 @@ const verticalRef = ref();
|
|||||||
const horizontalRef = ref();
|
const horizontalRef = ref();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
body,
|
|
||||||
dataTheme,
|
dataTheme,
|
||||||
layoutTheme,
|
layoutTheme,
|
||||||
themeColors,
|
themeColors,
|
||||||
@ -165,8 +164,6 @@ function setFalse(Doms): any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch($storage, ({ layout }) => {
|
watch($storage, ({ layout }) => {
|
||||||
/* 设置wangeditorV5主题色 */
|
|
||||||
body.style.setProperty("--w-e-toolbar-active-color", layout["epThemeColor"]);
|
|
||||||
switch (layout["layout"]) {
|
switch (layout["layout"]) {
|
||||||
case "vertical":
|
case "vertical":
|
||||||
toggleClass(true, isSelect, unref(verticalRef));
|
toggleClass(true, isSelect, unref(verticalRef));
|
||||||
|
@ -8,7 +8,6 @@ import { useGlobal } from "@pureadmin/utils";
|
|||||||
import { transformI18n } from "@/plugins/i18n";
|
import { transformI18n } from "@/plugins/i18n";
|
||||||
import { router, remainingPaths } from "@/router";
|
import { router, remainingPaths } from "@/router";
|
||||||
import { useAppStoreHook } from "@/store/modules/app";
|
import { useAppStoreHook } from "@/store/modules/app";
|
||||||
import { i18nChangeLanguage } from "@wangeditor/editor";
|
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
|
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||||
@ -136,15 +135,6 @@ export function useNav() {
|
|||||||
return remainingPaths.includes(path);
|
return remainingPaths.includes(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换wangEditorV5国际化
|
|
||||||
* @param language string 可选值 en、zh-CN
|
|
||||||
* @returns void
|
|
||||||
*/
|
|
||||||
function changeWangeditorLanguage(language: string): void {
|
|
||||||
i18nChangeLanguage(language);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
device,
|
device,
|
||||||
@ -164,7 +154,6 @@ export function useNav() {
|
|||||||
username,
|
username,
|
||||||
avatarsStyle,
|
avatarsStyle,
|
||||||
getDropdownItemStyle,
|
getDropdownItemStyle,
|
||||||
getDropdownItemClass,
|
getDropdownItemClass
|
||||||
changeWangeditorLanguage
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@ import { useRoute } from "vue-router";
|
|||||||
import { watch, type Ref } from "vue";
|
import { watch, type Ref } from "vue";
|
||||||
|
|
||||||
export function useTranslationLang(ref?: Ref) {
|
export function useTranslationLang(ref?: Ref) {
|
||||||
const { $storage, changeTitle, changeWangeditorLanguage, handleResize } =
|
const { $storage, changeTitle, handleResize } = useNav();
|
||||||
useNav();
|
|
||||||
const { locale, t } = useI18n();
|
const { locale, t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
@ -25,9 +24,6 @@ export function useTranslationLang(ref?: Ref) {
|
|||||||
() => locale.value,
|
() => locale.value,
|
||||||
() => {
|
() => {
|
||||||
changeTitle(route.meta);
|
changeTitle(route.meta);
|
||||||
locale.value === "en"
|
|
||||||
? changeWangeditorLanguage(locale.value)
|
|
||||||
: changeWangeditorLanguage("zh-CN");
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import "animate.css";
|
||||||
import { setType } from "./types";
|
import { setType } from "./types";
|
||||||
import { emitter } from "@/utils/mitt";
|
import { emitter } from "@/utils/mitt";
|
||||||
import { useLayout } from "./hooks/useLayout";
|
import { useLayout } from "./hooks/useLayout";
|
||||||
|
@ -8,13 +8,11 @@ import { createApp, Directive } from "vue";
|
|||||||
import { MotionPlugin } from "@vueuse/motion";
|
import { MotionPlugin } from "@vueuse/motion";
|
||||||
import { useEcharts } from "@/plugins/echarts";
|
import { useEcharts } from "@/plugins/echarts";
|
||||||
import { useTable } from "@/plugins/vxe-table";
|
import { useTable } from "@/plugins/vxe-table";
|
||||||
import VirtualScroller from "vue-virtual-scroller";
|
|
||||||
import { injectResponsiveStorage } from "@/utils/responsive";
|
import { injectResponsiveStorage } from "@/utils/responsive";
|
||||||
|
|
||||||
import Table from "@pureadmin/table";
|
import Table from "@pureadmin/table";
|
||||||
import PureDescriptions from "@pureadmin/descriptions";
|
import PureDescriptions from "@pureadmin/descriptions";
|
||||||
|
|
||||||
import "animate.css";
|
|
||||||
// 引入重置样式
|
// 引入重置样式
|
||||||
import "./style/reset.scss";
|
import "./style/reset.scss";
|
||||||
// 导入公共样式
|
// 导入公共样式
|
||||||
@ -23,8 +21,6 @@ import "element-plus/dist/index.css";
|
|||||||
// 导入字体图标
|
// 导入字体图标
|
||||||
import "./assets/iconfont/iconfont.js";
|
import "./assets/iconfont/iconfont.js";
|
||||||
import "./assets/iconfont/iconfont.css";
|
import "./assets/iconfont/iconfont.css";
|
||||||
import "v-contextmenu/dist/themes/default.css";
|
|
||||||
import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
|
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
@ -60,7 +56,6 @@ getServerConfig(app).then(async config => {
|
|||||||
.use(Table)
|
.use(Table)
|
||||||
.use(PureDescriptions)
|
.use(PureDescriptions)
|
||||||
.use(useTable)
|
.use(useTable)
|
||||||
.use(useEcharts)
|
.use(useEcharts);
|
||||||
.use(VirtualScroller);
|
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { IconSelect } from "@/components/ReIcon";
|
import IconSelect from "@/components/ReIcon/src/Select.vue";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "IconSelect"
|
name: "IconSelect"
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
import { faker } from "@faker-js/faker";
|
|
||||||
|
|
||||||
let uid = 0;
|
|
||||||
|
|
||||||
function generateItem() {
|
|
||||||
return {
|
|
||||||
name: faker.name.findName(),
|
|
||||||
avatar: faker.internet.avatar()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getData(count, letters) {
|
|
||||||
const raw = {};
|
|
||||||
|
|
||||||
const alphabet = "abcdefghijklmnopqrstuvwxyz".split("");
|
|
||||||
|
|
||||||
for (const l of alphabet) {
|
|
||||||
raw[l] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
const item = generateItem();
|
|
||||||
const letter = item.name.charAt(0).toLowerCase();
|
|
||||||
raw[letter].push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
const list = [];
|
|
||||||
let index = 1;
|
|
||||||
|
|
||||||
for (const l of alphabet) {
|
|
||||||
raw[l] = raw[l].sort((a, b) => (a.name < b.name ? -1 : 1));
|
|
||||||
if (letters) {
|
|
||||||
list.push({
|
|
||||||
id: uid++,
|
|
||||||
index: index++,
|
|
||||||
type: "letter",
|
|
||||||
value: l,
|
|
||||||
height: 200
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (const item of raw[l]) {
|
|
||||||
list.push({
|
|
||||||
id: uid++,
|
|
||||||
index: index++,
|
|
||||||
type: "person",
|
|
||||||
value: item,
|
|
||||||
height: 50
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addItem(list) {
|
|
||||||
list.push({
|
|
||||||
id: uid++,
|
|
||||||
index: list.length + 1,
|
|
||||||
type: "person",
|
|
||||||
value: generateItem(),
|
|
||||||
height: 50
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateMessage() {
|
|
||||||
return {
|
|
||||||
avatar: faker.internet.avatar(),
|
|
||||||
message: faker.lorem.text()
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,33 +1,27 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { generateMessage } from "./data";
|
import { DynamicScroller, DynamicScrollerItem } from "vue-virtual-scroller";
|
||||||
|
|
||||||
const items = ref([]);
|
const items = ref([]);
|
||||||
const search = ref("");
|
const search = ref("");
|
||||||
|
|
||||||
for (let i = 0; i < 10000; i++) {
|
for (let i = 0; i < 800; i++) {
|
||||||
items.value.push({
|
items.value.push({
|
||||||
id: i,
|
id: i
|
||||||
...generateMessage()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredItems = computed(() => {
|
const filteredItems = computed(() => {
|
||||||
if (!search.value) return items.value;
|
if (!search.value) return items.value;
|
||||||
const lowerCaseSearch = search.value.toLowerCase();
|
const lowerCaseSearch = search.value;
|
||||||
return items.value.filter(i =>
|
return items.value.filter(i => i.id == lowerCaseSearch);
|
||||||
i.message.toLowerCase().includes(lowerCaseSearch)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function changeMessage(message) {
|
|
||||||
Object.assign(message, generateMessage());
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dynamic-scroller-demo">
|
<div class="dynamic-scroller-demo">
|
||||||
<div class="flex justify-around mb-4">
|
<div class="flex-ac mb-4 shadow-2xl">
|
||||||
|
水平模式 horizontal
|
||||||
<el-input
|
<el-input
|
||||||
class="mr-2 !w-[1/1.5]"
|
class="mr-2 !w-[1/1.5]"
|
||||||
clearable
|
clearable
|
||||||
@ -35,7 +29,6 @@ function changeMessage(message) {
|
|||||||
placeholder="Filter..."
|
placeholder="Filter..."
|
||||||
style="width: 300px"
|
style="width: 300px"
|
||||||
/>
|
/>
|
||||||
<el-tag effect="dark">水平模式horizontal</el-tag>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DynamicScroller
|
<DynamicScroller
|
||||||
@ -48,31 +41,21 @@ function changeMessage(message) {
|
|||||||
<DynamicScrollerItem
|
<DynamicScrollerItem
|
||||||
:item="item"
|
:item="item"
|
||||||
:active="active"
|
:active="active"
|
||||||
:size-dependencies="[item.message]"
|
:size-dependencies="[item.id]"
|
||||||
:data-index="index"
|
:data-index="index"
|
||||||
:data-active="active"
|
:data-active="active"
|
||||||
:title="`Click to change message ${index}`"
|
:title="`Click to change message ${index}`"
|
||||||
:style="{
|
:style="{
|
||||||
width: `${Math.max(
|
width: `${Math.max(130, Math.round((item.id?.length / 20) * 20))}px`
|
||||||
130,
|
|
||||||
Math.round((item.message.length / 20) * 20)
|
|
||||||
)}px`
|
|
||||||
}"
|
}"
|
||||||
class="message"
|
class="message"
|
||||||
@click="changeMessage(item)"
|
|
||||||
>
|
>
|
||||||
<div class="avatar">
|
<div>
|
||||||
<IconifyIconOnline
|
<IconifyIconOnline
|
||||||
icon="openmoji:beaming-face-with-smiling-eyes"
|
icon="openmoji:beaming-face-with-smiling-eyes"
|
||||||
width="40"
|
width="40"
|
||||||
/>
|
/>
|
||||||
</div>
|
<p class="text-center">{{ item.id }}</p>
|
||||||
<div class="text">
|
|
||||||
{{ item.message }}
|
|
||||||
</div>
|
|
||||||
<div class="index">
|
|
||||||
<span>{{ item.id }} (id)</span>
|
|
||||||
<span>{{ index }} (index)</span>
|
|
||||||
</div>
|
</div>
|
||||||
</DynamicScrollerItem>
|
</DynamicScrollerItem>
|
||||||
</template>
|
</template>
|
||||||
@ -104,35 +87,4 @@ function changeMessage(message) {
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
|
||||||
flex: auto 0 0;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar .image {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.index,
|
|
||||||
.text {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.index {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.index span {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import verticalList from "./vertical.vue";
|
import verticalList from "./vertical.vue";
|
||||||
import horizontalList from "./horizontal.vue";
|
import horizontalList from "./horizontal.vue";
|
||||||
|
import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "VirtualList"
|
name: "VirtualList"
|
||||||
|
@ -1,75 +1,56 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { generateMessage } from "./data";
|
import { DynamicScroller, DynamicScrollerItem } from "vue-virtual-scroller";
|
||||||
|
|
||||||
const items = ref([]);
|
const items = ref([]);
|
||||||
const search = ref("");
|
const search = ref("");
|
||||||
|
|
||||||
for (let i = 0; i < 10000; i++) {
|
for (let i = 0; i < 800; i++) {
|
||||||
items.value.push({
|
items.value.push({
|
||||||
id: i,
|
id: i
|
||||||
...generateMessage()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredItems = computed(() => {
|
const filteredItems = computed(() => {
|
||||||
if (!search.value) return items.value;
|
if (!search.value) return items.value;
|
||||||
const lowerCaseSearch = search.value.toLowerCase();
|
const lowerCaseSearch = search.value;
|
||||||
return items.value.filter(i =>
|
return items.value.filter(i => i.id == lowerCaseSearch);
|
||||||
i.message.toLowerCase().includes(lowerCaseSearch)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function changeMessage(message) {
|
|
||||||
Object.assign(message, generateMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
function onResize() {
|
|
||||||
console.log("resize");
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dynamic-scroller-demo">
|
<div class="dynamic-scroller-demo">
|
||||||
<div class="flex justify-around mb-4">
|
<div class="flex-ac mb-4 shadow-2xl">
|
||||||
|
垂直模式 vertical
|
||||||
<el-input
|
<el-input
|
||||||
class="mr-2 !w-[1/1.5]"
|
class="!w-[350px]"
|
||||||
clearable
|
clearable
|
||||||
v-model="search"
|
v-model="search"
|
||||||
placeholder="Filter..."
|
placeholder="Filter..."
|
||||||
/>
|
/>
|
||||||
<el-tag effect="dark">垂直模式vertical</el-tag>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DynamicScroller
|
<DynamicScroller
|
||||||
:items="filteredItems"
|
:items="filteredItems"
|
||||||
:min-item-size="54"
|
:min-item-size="54"
|
||||||
class="scroller"
|
class="scroller"
|
||||||
@resize="onResize"
|
|
||||||
>
|
>
|
||||||
<template #default="{ item, index, active }">
|
<template #default="{ item, index, active }">
|
||||||
<DynamicScrollerItem
|
<DynamicScrollerItem
|
||||||
:item="item"
|
:item="item"
|
||||||
:active="active"
|
:active="active"
|
||||||
:size-dependencies="[item.message]"
|
:size-dependencies="[item.id]"
|
||||||
:data-index="index"
|
:data-index="index"
|
||||||
:data-active="active"
|
:data-active="active"
|
||||||
:title="`Click to change message ${index}`"
|
:title="`Click to change message ${index}`"
|
||||||
class="message"
|
class="message"
|
||||||
@click="changeMessage(item)"
|
|
||||||
>
|
>
|
||||||
<div class="avatar">
|
<div class="flex items-center">
|
||||||
<IconifyIconOnline
|
<IconifyIconOnline
|
||||||
icon="openmoji:beaming-face-with-smiling-eyes"
|
icon="openmoji:beaming-face-with-smiling-eyes"
|
||||||
width="40"
|
width="40"
|
||||||
/>
|
/>
|
||||||
</div>
|
<span>{{ item.id }}</span>
|
||||||
<div class="text">
|
|
||||||
{{ item.message }}
|
|
||||||
</div>
|
|
||||||
<div class="index">
|
|
||||||
<span>{{ item.id }} (id)</span>
|
|
||||||
<span>{{ index }} (index)</span>
|
|
||||||
</div>
|
</div>
|
||||||
</DynamicScrollerItem>
|
</DynamicScrollerItem>
|
||||||
</template>
|
</template>
|
||||||
@ -94,31 +75,4 @@ function onResize() {
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
|
||||||
flex: auto 0 0;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.index,
|
|
||||||
.text {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.index {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.index span {
|
|
||||||
display: inline-block;
|
|
||||||
width: 160px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import basic from "./basic.vue";
|
import basic from "./basic.vue";
|
||||||
import menuGroup from "./menuGroup.vue";
|
import menuGroup from "./menuGroup.vue";
|
||||||
import menuDynamic from "./menuDynamic.vue";
|
import menuDynamic from "./menuDynamic.vue";
|
||||||
|
import "v-contextmenu/dist/themes/default.css";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "ContextMenu"
|
name: "ContextMenu"
|
||||||
|
@ -195,7 +195,7 @@ onUnmounted(() => {
|
|||||||
>
|
>
|
||||||
<TypeIt
|
<TypeIt
|
||||||
:className="'type-it2'"
|
:className="'type-it2'"
|
||||||
:values="['Pure-Admin 版本日志']"
|
:values="['PureAdmin 版本日志']"
|
||||||
:cursor="false"
|
:cursor="false"
|
||||||
:speed="80"
|
:speed="80"
|
||||||
/>
|
/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user