refactor(components): 二次封装e-icon

This commit is contained in:
Coffee-crocodile 2022-08-11 13:58:28 +08:00
parent d5e46c3473
commit d8b0fec8c8
12 changed files with 158 additions and 119 deletions

19
src/components/EIcon.vue Normal file
View File

@ -0,0 +1,19 @@
<template>
<Icon :icon="props.icon" class="inline-block" :width="props.size" />
</template>
<script setup lang="ts">
import { Icon } from '@iconify/vue';
const props = defineProps({
icon: {
type: String,
default: 'icon-park-outline:game',
},
size: {
type: Number,
default: 18,
},
});
</script>
<style scoped></style>

View File

@ -1,25 +1,9 @@
<template>
<n-layout has-sider class="wh-full">
<n-layout-sider
bordered
show-trigger
:collapsed="collapsed"
:collapsed-width="64"
collapse-mode="width"
@collapse="collapsed = true"
@expand="collapsed = false"
>
<Logo :collapsed="collapsed" />
<n-menu
:collapsed="collapsed"
:collapsed-width="64"
:collapsed-icon-size="24"
:indent="20"
:options="menuOptions"
@update:value="handleClickMenu"
/>
<n-layout-sider bordered :collapsed="appStore.collapsed" :collapsed-width="64" collapse-mode="width">
<Logo />
<Menu />
</n-layout-sider>
<n-layout class="h-full bg-hex-f3f4f6" :native-scrollbar="false">
<n-layout-header bordered class="h-60px flex-y-center">
<CollapaseButton />
@ -36,78 +20,10 @@
</template>
<script lang="ts" setup>
import type { MenuOption } from 'naive-ui';
import { h, ref } from 'vue';
import { useRouter } from 'vue-router';
import { Icon } from '@iconify/vue';
import Logo from '../components/Logo.vue';
import Breadcrumb from '../components/Breadcrumb.vue';
import CollapaseButton from '../components/CollapaseButton.vue';
import { useApp } from '@/store';
import { Breadcrumb, CollapaseButton, Menu, Logo } from '../components';
const router = useRouter();
const collapsed = ref(false);
function renderIcon(icon: string) {
return () => h(Icon, { icon });
}
// const activeKey = ref('');
const handleClickMenu = (key: string, _item: MenuOption) => {
router.push(key);
};
const menuOptions: MenuOption[] = [
{
label: 'test1',
key: '/test1',
icon: renderIcon('icon-park-outline:alarm'),
},
{
label: 'test2',
key: '/test2',
icon: renderIcon('icon-park-outline:alarm'),
},
{
label: 'test3',
key: '/test3',
icon: renderIcon('icon-park-outline:alarm'),
},
{
label: '登录页',
key: '/login',
icon: renderIcon('icon-park-outline:alarm'),
},
{
label: '舞,舞,舞',
key: 'dance-dance-dance',
icon: renderIcon('icon-park-outline:alarm'),
children: [
{
label: '饮品',
key: 'beverage',
// icon: renderIcon(WineIcon),
children: [
{
label: '威士忌',
key: 'whisky',
},
],
},
{
label: '食物',
key: 'food',
children: [
{
label: '三明治',
key: 'sandwich',
},
],
},
{
label: '过去增多,未来减少',
key: 'the-past-increases-the-future-recedes',
},
],
},
];
const appStore = useApp();
</script>
<style scoped></style>

View File

@ -1,11 +1,11 @@
<template>
<n-breadcrumb>
<n-breadcrumb-item class="align-middle">
<Icon icon="icon-park-outline:home-two" class="inline-block" width="16" />
<e-icon icon="icon-park-outline:home-two" />
首页
</n-breadcrumb-item>
<n-breadcrumb-item v-for="(item, index) in routes" :key="index">
<Icon :icon="item.meta.icon" class="inline-block" width="18" />
<e-icon :icon="item.meta.icon" />
{{ item.meta.title }}
</n-breadcrumb-item>
</n-breadcrumb>
@ -17,16 +17,6 @@ import { useRouter } from 'vue-router';
import { Icon } from '@iconify/vue';
const router = useRouter();
// const props = defineProps({
// title: {
// type: String,
// default: 'Logo2',
// },
// collapsed: {
// type: Boolean,
// default: false,
// },
// });
const routes = computed(() => {
return router.currentRoute.value.matched.filter((item) => {
return item.meta.title;

View File

@ -1,11 +1,16 @@
<template>
<div class="hover:bg-hex-F3F4F6 hover:shadow-inner h-full px-2 flex-center cursor-pointer">
<Icon icon="icon-park-outline:music-list" class="inline-block" width="18" />
<div
class="hover:bg-hex-F3F4F6 hover:shadow-inner h-full px-2 flex-center cursor-pointer"
@click="appStore.switchCollapse()"
>
<e-icon v-show="appStore.collapsed" icon="icon-park-outline:menu-unfold" />
<e-icon v-show="!appStore.collapsed" icon="icon-park-outline:menu-fold" />
</div>
</template>
<script setup lang="ts">
import { Icon } from '@iconify/vue';
import { useApp } from '@/store';
const appStore = useApp();
</script>
<style scoped></style>

View File

@ -0,0 +1,85 @@
<template>
<n-menu
:collapsed="appStore.collapsed"
:collapsed-width="64"
:collapsed-icon-size="24"
:indent="20"
:options="menuOptions"
@update:value="handleClickMenu"
/>
</template>
<script setup lang="ts">
import { useApp } from '@/store';
import { Icon } from '@iconify/vue';
import { useRouter } from 'vue-router';
import { h } from 'vue';
import type { MenuOption } from 'naive-ui';
const appStore = useApp();
const router = useRouter();
function renderIcon(icon: string) {
return () => h(Icon, { icon });
}
const handleClickMenu = (key: string, _item: MenuOption) => {
router.push(key);
};
const menuOptions: MenuOption[] = [
{
label: 'test1',
key: '/test1',
icon: renderIcon('icon-park-outline:alarm'),
},
{
label: 'test2',
key: '/test2',
icon: renderIcon('icon-park-outline:tool'),
},
{
label: 'test3',
key: '/test3',
icon: renderIcon('icon-park-outline:pic'),
},
{
label: '登录页',
key: '/login',
icon: renderIcon('icon-park-outline:save'),
},
{
label: '舞,舞,舞',
key: 'dance-dance-dance',
icon: renderIcon('icon-park-outline:command'),
children: [
{
label: '饮品',
key: 'beverage',
// icon: renderIcon(WineIcon),
children: [
{
label: '威士忌',
key: 'whisky',
},
],
},
{
label: '食物',
key: 'food',
children: [
{
label: '三明治',
key: 'sandwich',
},
],
},
{
label: '过去增多,未来减少',
key: 'the-past-increases-the-future-recedes',
},
],
},
];
</script>
<style scoped></style>

View File

@ -0,0 +1,6 @@
import Breadcrumb from './Breadcrumb.vue';
import CollapaseButton from './CollapaseButton.vue';
import Logo from './Logo.vue';
import Menu from './Menu.vue';
export { Breadcrumb, CollapaseButton, Menu, Logo };

View File

@ -1,21 +1,13 @@
<template>
<div class="h-60px text-2xl flex-center">
<div class="h-60px text-2xl flex-center overflow-hidden">
<SvgIcon name="logo" class="w-9 h-9" />
<span v-show="!props.collapsed" class="mx-5">{{ props.title }}</span>
<div v-show="!appStore.collapsed" class="mx-5">{{ appStore.title }}</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
title: {
type: String,
default: 'Logo2',
},
collapsed: {
type: Boolean,
default: false,
},
});
import { useApp } from '@/store';
const appStore = useApp();
</script>
<style scoped></style>

View File

@ -5,3 +5,4 @@ export function setupStore(app: App) {
const store = createPinia();
app.use(store);
}
export * from './modules';

15
src/store/modules/app.ts Normal file
View File

@ -0,0 +1,15 @@
import { defineStore } from 'pinia';
export const useApp = defineStore('app-store', {
state: () => {
return {
collapsed: false,
title: import.meta.env.VITE_APP_TITLE,
};
},
actions: {
switchCollapse() {
this.collapsed = !this.collapsed;
},
},
});

View File

@ -0,0 +1,9 @@
import { defineStore } from 'pinia';
export const useAuth = defineStore('auth-store', {
state: () => {
return {
name: '张三',
};
},
});

View File

@ -1 +1,2 @@
export * from './user';
export * from './app';

View File

@ -1,11 +1,11 @@
<template>
<div text-center c-yellow>I prove that you have made the jump test2.</div>
<div text-center c-yellow>I prove that you have made the ju mp test2.</div>
{{ userStore.name }}
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router';
import { useStore } from '@/store/modules';
import { useStore } from '@/store';
const userStore = useStore();