写添加菜单
This commit is contained in:
parent
fd361f332c
commit
3d5b72aea1
1
app.vue
1
app.vue
@ -3,5 +3,6 @@
|
||||
<template>
|
||||
<NuxtLayout>
|
||||
<NuxtPage />
|
||||
<NiMessage/>
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
|
@ -1,3 +1,12 @@
|
||||
@import "../fonts/vfonts/Lato.css";
|
||||
@import "../fonts/vfonts/FiraCode.css";
|
||||
@import "../icon/startMessage/iconfont.css";
|
||||
|
||||
[data-prefix^="Ni"] {
|
||||
font-family: v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
}
|
||||
|
||||
|
||||
/*宽高比*/
|
||||
.a11 {
|
||||
aspect-ratio: 1;
|
||||
@ -39,10 +48,15 @@
|
||||
--Ni-theme-color-T3: #e8e8e7;
|
||||
--Ni-theme-color-T4: #EFEFED;
|
||||
--Ni-theme-color-T0-10: #37352f11;
|
||||
--Ni-theme-color-T0-40: #37352f44;
|
||||
--Ni-theme-color-T0-60: #37352f66;
|
||||
--Ni-theme-color-T0-80: #37352f88;
|
||||
--Ni-theme-color-T0-a0: #37352faa;
|
||||
--Ni-theme-color-T0-c0: #37352fcc;
|
||||
--Ni-theme-color: var(--Ni-theme-color-T0);
|
||||
|
||||
--Ni-theme-color: var(--Ni-theme-color-T1);
|
||||
--Ni-theme-border-color: var(--Ni-theme-color-T0-40);
|
||||
--Ni-theme-border-color-hover: var(--Ni-theme-color-T0-c0);
|
||||
|
||||
|
||||
|
||||
@ -66,6 +80,15 @@
|
||||
--Ni-M-A: 1rem;
|
||||
/*tertiary*/
|
||||
|
||||
/*default*/
|
||||
--Ni-button-default-bg-default: #fefefe;
|
||||
--Ni-button-default-bg-hover: #91918e33;
|
||||
--Ni-button-default-bg-click: #37352f33;
|
||||
/*浅色*/
|
||||
--Ni-button-default-bg-default-light: #5f5e5b29;/*29-16*/
|
||||
--Ni-button-default-bg-hover-light: #91918e38;/*38-22*/
|
||||
--Ni-button-default-bg-click-light: #37352f47;/*47-28*/
|
||||
|
||||
/*primary*/
|
||||
--Ni-button-primary-bg-default: #5f5e5b;
|
||||
--Ni-button-primary-bg-hover: #91918e;
|
||||
|
5
assets/fonts/vfonts/FiraCode.css
Normal file
5
assets/fonts/vfonts/FiraCode.css
Normal file
@ -0,0 +1,5 @@
|
||||
@font-face {
|
||||
font-family: "v-mono";
|
||||
font-weight: 400;
|
||||
src: url("./assets/FiraCode-Regular.woff2");
|
||||
}
|
11
assets/fonts/vfonts/FiraSans.css
Normal file
11
assets/fonts/vfonts/FiraSans.css
Normal file
@ -0,0 +1,11 @@
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 400;
|
||||
src: url("./assets/FiraSans-Regular.woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 500;
|
||||
src: url("./assets/FiraSans-Medium.woff2");
|
||||
}
|
5
assets/fonts/vfonts/IBMPlexMono.css
Normal file
5
assets/fonts/vfonts/IBMPlexMono.css
Normal file
@ -0,0 +1,5 @@
|
||||
@font-face {
|
||||
font-family: "v-mono";
|
||||
font-weight: 400;
|
||||
src: url("./assets/IBMPlexMono-Regular.ttf");
|
||||
}
|
11
assets/fonts/vfonts/IBMPlexSans.css
Normal file
11
assets/fonts/vfonts/IBMPlexSans.css
Normal file
@ -0,0 +1,11 @@
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 400;
|
||||
src: url("./assets/IBMPlexSans-Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 500;
|
||||
src: url("./assets/IBMPlexSans-Medium.ttf");
|
||||
}
|
11
assets/fonts/vfonts/Inter.css
Normal file
11
assets/fonts/vfonts/Inter.css
Normal file
@ -0,0 +1,11 @@
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 400;
|
||||
src: url("./assets/Inter-Regular.woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 500;
|
||||
src: url("./assets/Inter-Medium.woff2");
|
||||
}
|
11
assets/fonts/vfonts/Lato.css
Normal file
11
assets/fonts/vfonts/Lato.css
Normal file
@ -0,0 +1,11 @@
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 400;
|
||||
src: url("./assets/LatoLatin-Regular.woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 600;
|
||||
src: url("./assets/LatoLatin-Semibold.woff2");
|
||||
}
|
11
assets/fonts/vfonts/OpenSans.css
Normal file
11
assets/fonts/vfonts/OpenSans.css
Normal file
@ -0,0 +1,11 @@
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 400;
|
||||
src: url("./assets/OpenSans-Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 600;
|
||||
src: url("./assets/OpenSans-SemiBold.ttf");
|
||||
}
|
44
assets/fonts/vfonts/README.md
Normal file
44
assets/fonts/vfonts/README.md
Normal file
@ -0,0 +1,44 @@
|
||||
# vfonts
|
||||
Integreted fonts for easy usage.
|
||||
|
||||
## Usage
|
||||
```js
|
||||
// in your js
|
||||
import 'vfonts/{font-name}.css'
|
||||
// for available fonts, see the following section
|
||||
```
|
||||
```css
|
||||
/** in your css */
|
||||
selector {
|
||||
font-family: v-sans, v-mono, other-fallbacks;
|
||||
}
|
||||
|
||||
/** for available font weights, see the following section */
|
||||
selector {
|
||||
font-weight: 400; /** regular */
|
||||
}
|
||||
|
||||
selector {
|
||||
font-weight: 500; /** medium */
|
||||
}
|
||||
```
|
||||
|
||||
## Available Fonts
|
||||
### `v-sans`
|
||||
- `FiraSans.css`
|
||||
- font weight `400`, `500`
|
||||
- `IBMPlexSans.css`
|
||||
- font weight `400`, `500`
|
||||
- `Inter.css`
|
||||
- font weight `400`, `500`
|
||||
- `Lato.css`
|
||||
- font weight `400`, `600`
|
||||
- `OpenSans.css`
|
||||
- font weight `400`, `600`
|
||||
- `Roboto.css`
|
||||
- font weight `400`, `500`
|
||||
- `RobotoSlab.css`
|
||||
- font weight `400`, `500`
|
||||
### `v-mono`
|
||||
- `FiraCode.css`
|
||||
- font weight `400`
|
11
assets/fonts/vfonts/Roboto.css
Normal file
11
assets/fonts/vfonts/Roboto.css
Normal file
@ -0,0 +1,11 @@
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 400;
|
||||
src: url("./assets/Roboto-Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 500;
|
||||
src: url("./assets/Roboto-Medium.ttf");
|
||||
}
|
11
assets/fonts/vfonts/RobotoSlab.css
Normal file
11
assets/fonts/vfonts/RobotoSlab.css
Normal file
@ -0,0 +1,11 @@
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 400;
|
||||
src: url("./assets/RobotoSlab-Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "v-sans";
|
||||
font-weight: 500;
|
||||
src: url("./assets/RobotoSlab-Medium.ttf");
|
||||
}
|
BIN
assets/fonts/vfonts/assets/FiraCode-Regular.woff2
Normal file
BIN
assets/fonts/vfonts/assets/FiraCode-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/FiraSans-Medium.woff2
Normal file
BIN
assets/fonts/vfonts/assets/FiraSans-Medium.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/FiraSans-Regular.woff2
Normal file
BIN
assets/fonts/vfonts/assets/FiraSans-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/IBMPlexMono-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/IBMPlexMono-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/IBMPlexSans-Medium.ttf
Normal file
BIN
assets/fonts/vfonts/assets/IBMPlexSans-Medium.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/IBMPlexSans-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/IBMPlexSans-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/Inter-Medium.woff2
Normal file
BIN
assets/fonts/vfonts/assets/Inter-Medium.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/Inter-Regular.woff2
Normal file
BIN
assets/fonts/vfonts/assets/Inter-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/LatoLatin-Regular.woff2
Normal file
BIN
assets/fonts/vfonts/assets/LatoLatin-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/LatoLatin-Semibold.woff2
Normal file
BIN
assets/fonts/vfonts/assets/LatoLatin-Semibold.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/OpenSans-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/OpenSans-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/OpenSans-SemiBold.ttf
Normal file
BIN
assets/fonts/vfonts/assets/OpenSans-SemiBold.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/Roboto-Medium.ttf
Normal file
BIN
assets/fonts/vfonts/assets/Roboto-Medium.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/Roboto-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/Roboto-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/RobotoSlab-Medium.ttf
Normal file
BIN
assets/fonts/vfonts/assets/RobotoSlab-Medium.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/RobotoSlab-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/RobotoSlab-Regular.ttf
Normal file
Binary file not shown.
93
assets/fonts/vfonts/font-license/FiraCode-LISCENSE.txt
Normal file
93
assets/fonts/vfonts/font-license/FiraCode-LISCENSE.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright (c) 2014, The Fira Code Project Authors (https://github.com/tonsky/FiraCode)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
1
assets/fonts/vfonts/font-license/FiraSans-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/FiraSans-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
||||
FiraSans is licensed under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL).
|
93
assets/fonts/vfonts/font-license/IBMPlex-LISCENSE.txt
Normal file
93
assets/fonts/vfonts/font-license/IBMPlex-LISCENSE.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
94
assets/fonts/vfonts/font-license/Inter-LISCENSE.txt
Normal file
94
assets/fonts/vfonts/font-license/Inter-LISCENSE.txt
Normal file
@ -0,0 +1,94 @@
|
||||
Copyright (c) 2016-2020 The Inter Project Authors.
|
||||
"Inter" is trademark of Rasmus Andersson.
|
||||
https://github.com/rsms/inter
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION AND CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
1
assets/fonts/vfonts/font-license/Lato-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/Lato-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
||||
Lato is licensed under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL).
|
1
assets/fonts/vfonts/font-license/OpenSans-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/OpenSans-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
||||
Open Sans is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
1
assets/fonts/vfonts/font-license/Roboto-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/Roboto-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
||||
Roboto is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
1
assets/fonts/vfonts/font-license/RobotoSlab-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/RobotoSlab-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
||||
Roboto is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
539
assets/icon/startMessage/demo.css
Normal file
539
assets/icon/startMessage/demo.css
Normal file
@ -0,0 +1,539 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: "iconfont logo";
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: "iconfont logo";
|
||||
font-size: 160px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
cursor: pointer;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
border-bottom: 2px solid transparent;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: -1px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
padding: 30px 100px;
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
color: #333;
|
||||
text-align: left;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
font-size: 160px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
width: 100% !important;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
list-style: none !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
font-size: 42px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
transition: font-size 0.25s linear, width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentColor;
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
color: #404040;
|
||||
margin: 1.6em 0 0.6em 0;
|
||||
font-weight: 500;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
margin: 16px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown>p,
|
||||
.markdown>blockquote,
|
||||
.markdown>.highlight,
|
||||
.markdown>ol,
|
||||
.markdown>ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul>li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown>ul li,
|
||||
.markdown blockquote ul>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown>ul li p,
|
||||
.markdown>ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol>li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown>ol li,
|
||||
.markdown blockquote ol>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
background: #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
empty-cells: show;
|
||||
border: 1px solid #e9e9e9;
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table th,
|
||||
.markdown>table td {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
font-size: 90%;
|
||||
color: #999;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
padding-left: 0.8em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
opacity: 1;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown>br,
|
||||
.markdown>p>br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre)>code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre)>code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
280
assets/icon/startMessage/demo_index.html
Normal file
280
assets/icon/startMessage/demo_index.html
Normal file
@ -0,0 +1,280 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>iconfont Demo</title>
|
||||
<link rel="shortcut icon" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg" type="image/x-icon"/>
|
||||
<link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg"/>
|
||||
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
|
||||
<link rel="stylesheet" href="demo.css">
|
||||
<link rel="stylesheet" href="iconfont.css">
|
||||
<script src="iconfont.js"></script>
|
||||
<!-- jQuery -->
|
||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
|
||||
<!-- 代码高亮 -->
|
||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
|
||||
<style>
|
||||
.main .logo {
|
||||
margin-top: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.main .logo .sub-title {
|
||||
margin-left: 0.5em;
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
background: linear-gradient(-45deg, #3967FF, #B500FE);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
|
||||
<img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
|
||||
|
||||
</a></h1>
|
||||
<div class="nav-tabs">
|
||||
<ul id="tabs" class="dib-box">
|
||||
<li class="dib active"><span>Unicode</span></li>
|
||||
<li class="dib"><span>Font class</span></li>
|
||||
<li class="dib"><span>Symbol</span></li>
|
||||
</ul>
|
||||
|
||||
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=4906634" target="_blank" class="nav-more">查看项目</a>
|
||||
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon startMessage"></span>
|
||||
<div class="name">error-fill</div>
|
||||
<div class="code-name">&#xe839;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon startMessage"></span>
|
||||
<div class="name">info-fill</div>
|
||||
<div class="code-name">&#xe83d;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon startMessage"></span>
|
||||
<div class="name">success-fill</div>
|
||||
<div class="code-name">&#xe842;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon startMessage"></span>
|
||||
<div class="name">user-defined-fill</div>
|
||||
<div class="code-name">&#xe871;</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="unicode-">Unicode 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
|
||||
<ul>
|
||||
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
|
||||
<li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
|
||||
</blockquote>
|
||||
<p>Unicode 使用步骤如下:</p>
|
||||
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'startMessage';
|
||||
src: url('iconfont.woff2?t=1745672562595') format('woff2'),
|
||||
url('iconfont.woff?t=1745672562595') format('woff'),
|
||||
url('iconfont.ttf?t=1745672562595') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
<pre><code class="language-css"
|
||||
>.startMessage {
|
||||
font-family: "startMessage" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
|
||||
<pre>
|
||||
<code class="language-html"
|
||||
><span class="startMessage">&#x33;</span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>"startMessage" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon startMessage startMessageerror-fill"></span>
|
||||
<div class="name">
|
||||
error-fill
|
||||
</div>
|
||||
<div class="code-name">.startMessageerror-fill
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon startMessage startMessageinfo-fill"></span>
|
||||
<div class="name">
|
||||
info-fill
|
||||
</div>
|
||||
<div class="code-name">.startMessageinfo-fill
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon startMessage startMessagesuccess-fill"></span>
|
||||
<div class="name">
|
||||
success-fill
|
||||
</div>
|
||||
<div class="code-name">.startMessagesuccess-fill
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon startMessage startMessageuser-defined-fill"></span>
|
||||
<div class="name">
|
||||
user-defined-fill
|
||||
</div>
|
||||
<div class="code-name">.startMessageuser-defined-fill
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="font-class-">font-class 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
|
||||
<p>与 Unicode 使用方式相比,具有如下特点:</p>
|
||||
<ul>
|
||||
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
|
||||
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
|
||||
</ul>
|
||||
<p>使用步骤如下:</p>
|
||||
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
|
||||
<pre><code class="language-html"><link rel="stylesheet" href="./iconfont.css">
|
||||
</code></pre>
|
||||
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||
<pre><code class="language-html"><span class="startMessage startMessagexxx"></span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>"
|
||||
startMessage" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#startMessageerror-fill"></use>
|
||||
</svg>
|
||||
<div class="name">error-fill</div>
|
||||
<div class="code-name">#startMessageerror-fill</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#startMessageinfo-fill"></use>
|
||||
</svg>
|
||||
<div class="name">info-fill</div>
|
||||
<div class="code-name">#startMessageinfo-fill</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#startMessagesuccess-fill"></use>
|
||||
</svg>
|
||||
<div class="name">success-fill</div>
|
||||
<div class="code-name">#startMessagesuccess-fill</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#startMessageuser-defined-fill"></use>
|
||||
</svg>
|
||||
<div class="name">user-defined-fill</div>
|
||||
<div class="code-name">#startMessageuser-defined-fill</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="symbol-">Symbol 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
|
||||
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
|
||||
<ul>
|
||||
<li>支持多色图标了,不再受单色限制。</li>
|
||||
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
|
||||
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
|
||||
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
|
||||
</ul>
|
||||
<p>使用步骤如下:</p>
|
||||
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
|
||||
<pre><code class="language-html"><script src="./iconfont.js"></script>
|
||||
</code></pre>
|
||||
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
|
||||
<pre><code class="language-html"><style>
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</code></pre>
|
||||
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||
<pre><code class="language-html"><svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-xxx"></use>
|
||||
</svg>
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('.tab-container .content:first').show()
|
||||
|
||||
$('#tabs li').click(function (e) {
|
||||
var tabContent = $('.tab-container .content')
|
||||
var index = $(this).index()
|
||||
|
||||
if ($(this).hasClass('active')) {
|
||||
return
|
||||
} else {
|
||||
$('#tabs li').removeClass('active')
|
||||
$(this).addClass('active')
|
||||
|
||||
tabContent.hide().eq(index).fadeIn()
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
31
assets/icon/startMessage/iconfont.css
Normal file
31
assets/icon/startMessage/iconfont.css
Normal file
@ -0,0 +1,31 @@
|
||||
@font-face {
|
||||
font-family: "startMessageIconFont"; /* Project id 4906634 */
|
||||
src: url('iconfont.woff2?t=1745672562595') format('woff2'),
|
||||
url('iconfont.woff?t=1745672562595') format('woff'),
|
||||
url('iconfont.ttf?t=1745672562595') format('truetype');
|
||||
}
|
||||
|
||||
.startMessageIconFont {
|
||||
font-family: "startMessageIconFont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.startMessageerror-fill:before {
|
||||
content: "\e839";
|
||||
}
|
||||
|
||||
.startMessageinfo-fill:before {
|
||||
content: "\e83d";
|
||||
}
|
||||
|
||||
.startMessagesuccess-fill:before {
|
||||
content: "\e842";
|
||||
}
|
||||
|
||||
.startMessageuser-defined-fill:before {
|
||||
content: "\e871";
|
||||
}
|
||||
|
1
assets/icon/startMessage/iconfont.js
Normal file
1
assets/icon/startMessage/iconfont.js
Normal file
@ -0,0 +1 @@
|
||||
window._iconfont_svg_string_4906634='<svg><symbol id="startMessageerror-fill" viewBox="0 0 1024 1024"><path d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m129.29219 233.447619l-129.267809 129.29219-129.316571-129.29219-51.736381 51.736381 129.316571 129.267809-129.316571 129.316571 51.736381 51.736381L512 563.687619l129.29219 129.316571 51.736381-51.73638L563.687619 512l129.316571-129.29219-51.73638-51.736381z" ></path></symbol><symbol id="startMessageinfo-fill" viewBox="0 0 1024 1024"><path d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m36.571429 341.333333h-73.142858v292.571428h73.142858V438.857143z m0-121.904762h-73.142858v73.142857h73.142858v-73.142857z" ></path></symbol><symbol id="startMessagesuccess-fill" viewBox="0 0 1024 1024"><path d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m193.194667 218.331428L447.21981 581.315048l-103.936-107.812572-52.662858 50.761143 156.379429 162.230857 310.662095-319.683047-52.467809-50.956191z" ></path></symbol><symbol id="startMessageuser-defined-fill" viewBox="0 0 1024 1024"><path d="M512 134.095238c212.089905 0 377.904762 148.187429 377.904762 354.279619 0 56.56381-17.871238 98.986667-64.926476 117.857524-18.358857 7.338667-36.230095 8.704-56.173715 6.802286-6.144-0.585143-12.263619-1.462857-19.407238-2.681905l-22.186666-4.022857c-29.842286-5.12-43.032381-3.900952-56.783238 5.144381-5.851429 3.876571-11.995429 9.411048-18.456381 17.066666-18.041905 21.382095-20.358095 38.034286-11.117715 73.289143l3.120762 11.166476 4.559238 15.408762 2.730667 9.654857c1.584762 5.851429 2.852571 11.093333 3.900952 16.335239 4.705524 23.844571 4.559238 45.29981-4.461714 67.535238C629.808762 873.569524 582.851048 889.904762 512 889.904762c-208.700952 0-377.904762-169.20381-377.904762-377.904762 0-208.700952 169.20381-377.904762 377.904762-377.904762z m-27.306667 509.44a73.142857 73.142857 0 1 0-144.847238 20.358095 73.142857 73.142857 0 0 0 144.847238-20.358095z m-33.913904-241.444571a73.142857 73.142857 0 1 0-144.871619 20.358095 73.142857 73.142857 0 0 0 144.871619-20.358095zM692.175238 368.152381a73.142857 73.142857 0 1 0-144.847238 20.358095 73.142857 73.142857 0 0 0 144.847238-20.358095z" ></path></symbol></svg>',(n=>{var e=(t=(t=document.getElementsByTagName("script"))[t.length-1]).getAttribute("data-injectcss"),t=t.getAttribute("data-disable-injectsvg");if(!t){var o,i,s,a,l,d=function(e,t){t.parentNode.insertBefore(e,t)};if(e&&!n.__iconfont__svg__cssinject__){n.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(e){console&&console.log(e)}}o=function(){var e,t=document.createElement("div");t.innerHTML=n._iconfont_svg_string_4906634,(t=t.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",t=t,(e=document.body).firstChild?d(t,e.firstChild):e.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(o,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),o()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(s=o,a=n.document,l=!1,r(),a.onreadystatechange=function(){"complete"==a.readyState&&(a.onreadystatechange=null,c())})}function c(){l||(l=!0,s())}function r(){try{a.documentElement.doScroll("left")}catch(e){return void setTimeout(r,50)}c()}})(window);
|
37
assets/icon/startMessage/iconfont.json
Normal file
37
assets/icon/startMessage/iconfont.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"id": "4906634",
|
||||
"name": "startMessage",
|
||||
"font_family": "startMessage",
|
||||
"css_prefix_text": "startMessage",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "34452976",
|
||||
"name": "error-fill",
|
||||
"font_class": "error-fill",
|
||||
"unicode": "e839",
|
||||
"unicode_decimal": 59449
|
||||
},
|
||||
{
|
||||
"icon_id": "34453007",
|
||||
"name": "info-fill",
|
||||
"font_class": "info-fill",
|
||||
"unicode": "e83d",
|
||||
"unicode_decimal": 59453
|
||||
},
|
||||
{
|
||||
"icon_id": "34453063",
|
||||
"name": "success-fill",
|
||||
"font_class": "success-fill",
|
||||
"unicode": "e842",
|
||||
"unicode_decimal": 59458
|
||||
},
|
||||
{
|
||||
"icon_id": "34453306",
|
||||
"name": "user-defined-fill",
|
||||
"font_class": "user-defined-fill",
|
||||
"unicode": "e871",
|
||||
"unicode_decimal": 59505
|
||||
}
|
||||
]
|
||||
}
|
BIN
assets/icon/startMessage/iconfont.ttf
Normal file
BIN
assets/icon/startMessage/iconfont.ttf
Normal file
Binary file not shown.
BIN
assets/icon/startMessage/iconfont.woff
Normal file
BIN
assets/icon/startMessage/iconfont.woff
Normal file
Binary file not shown.
BIN
assets/icon/startMessage/iconfont.woff2
Normal file
BIN
assets/icon/startMessage/iconfont.woff2
Normal file
Binary file not shown.
@ -27,7 +27,7 @@
|
||||
align-items: center;
|
||||
.logoContent{
|
||||
position: relative;
|
||||
padding: 5px 20px;
|
||||
padding: 2.5px 20px;
|
||||
& > div{
|
||||
position: relative;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div data-prefix="Ni">
|
||||
<slot/>
|
||||
<div id="NiBaseNotificationContainer"></div>
|
||||
</div>
|
||||
|
@ -4,7 +4,7 @@ const props = defineProps({
|
||||
// 按钮类型
|
||||
type: String,
|
||||
default: 'default',
|
||||
validator: (value: string) => ['default', 'tertiary', 'primary', 'info', 'success', 'warning', 'error'].includes(value)
|
||||
validator: (value: string) => ['default', 'primary', 'info', 'success', 'warning', 'error'].includes(value)
|
||||
},
|
||||
strong: {
|
||||
// 加粗
|
||||
@ -34,7 +34,13 @@ const props = defineProps({
|
||||
default: false,
|
||||
}
|
||||
})
|
||||
consola.info(toValue(props))
|
||||
const emit = defineEmits(['click']);
|
||||
|
||||
const handleClick = () => {
|
||||
if (!props.disabled && !props.loading) {
|
||||
emit('click');
|
||||
}
|
||||
};
|
||||
const typeS = ref(props.type);
|
||||
const strong = ref(props.strong);
|
||||
const grade = ref(props.grade);
|
||||
@ -57,6 +63,7 @@ const NiButtonClass = computed(() => {
|
||||
grade.value == 'light' ? 'light' : '',
|
||||
grade.value == 'halfTransparent' ? 'halfTransparent' : '',
|
||||
grade.value == 'transparent' ? 'transparent' : '',
|
||||
typeS.value == 'default' ? 'defaultType' : '',
|
||||
].join(' ');
|
||||
})
|
||||
const style = computed(() => {
|
||||
@ -86,10 +93,11 @@ const style = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template data-prefix="Ni">
|
||||
<div class="NiButton"
|
||||
:style
|
||||
:class="NiButtonClass"
|
||||
@click="handleClick"
|
||||
>
|
||||
<slot name="icons"/>
|
||||
<span v-if="loading" class="sxIconFont" :class="loading && 'loading'"></span>
|
||||
@ -118,10 +126,10 @@ const style = computed(() => {
|
||||
align-items: center;
|
||||
background-color: var(--NiButton-bg-default);
|
||||
color: var(--NiButton-color-default);
|
||||
border: 1px solid var(--NiButton-bg-default);
|
||||
padding: var(--Ni-button-padding);
|
||||
width: fit-content;
|
||||
height: var(--Ni-button-height);
|
||||
border: 1px solid var(--NiButton-bg-default);
|
||||
cursor: pointer;
|
||||
transition: color .3s ease-in-out, background-color .3s ease-in-out, border-color .3s ease-in-out, width .3s ease-in-out;
|
||||
//height: var(--Ni-button-height);
|
||||
@ -139,6 +147,21 @@ const style = computed(() => {
|
||||
border: 1px solid var(--NiButton-bg-click);
|
||||
}
|
||||
}
|
||||
.NiButton.defaultType{
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
color: var(--Ni-theme-color-T1);
|
||||
border: 1px solid var(--Ni-theme-border-color);
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
color: var(--Ni-theme-color-T2);
|
||||
border: 1px solid var(--Ni-theme-border-color-hover);
|
||||
}
|
||||
&:active {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
color: var(--Ni-theme-color-T0);
|
||||
border: 1px solid var(--Ni-theme-color-T0);
|
||||
}
|
||||
}
|
||||
.NiButton.disabled{
|
||||
opacity: var(--Ni-button-disable-opacity);
|
||||
cursor: not-allowed;
|
||||
|
23
components/Ni/Form.vue
Normal file
23
components/Ni/Form.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
data: {
|
||||
// 表单数据
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
rules:{
|
||||
// 表单数据
|
||||
type: Object,
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="NiForm" data-prefix="Ni">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
69
components/Ni/FormItem.vue
Normal file
69
components/Ni/FormItem.vue
Normal file
@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
label: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
name:{
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
labelWidth: {
|
||||
type: String,
|
||||
default: '8',
|
||||
}
|
||||
})
|
||||
const itemLabel = ref('')
|
||||
const itemName = ref('')
|
||||
const itemLabelWidth = ref('8')
|
||||
|
||||
watchEffect(() => {
|
||||
itemLabel.value = props.label
|
||||
itemName.value = props.name
|
||||
itemLabelWidth.value = props.labelWidth
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="NiFormItem" data-prefix="Ni">
|
||||
<div class="content">
|
||||
<div class="formLabel" :style="{width: itemLabelWidth+'em'}">
|
||||
<span>{{itemLabel}}</span>
|
||||
</div>
|
||||
<div class="formValue"><slot/></div>
|
||||
</div>
|
||||
<div class="feedback"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.NiFormItem{
|
||||
position: relative;
|
||||
height: 3.6rem;
|
||||
padding: .5rem 0;
|
||||
|
||||
& > div.content{
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: 2.4rem;
|
||||
|
||||
&>div.formLabel{
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
font-weight: bold;
|
||||
color: var(--Ni-theme-color);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
&>div.formValue{
|
||||
position: relative;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
& > div.feedback{
|
||||
position: relative;
|
||||
height: 1.2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
118
components/Ni/Input.vue
Normal file
118
components/Ni/Input.vue
Normal file
@ -0,0 +1,118 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
modelValue: { // v-model 默认接收的属性
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
clear: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
// 按钮类型
|
||||
type: String,
|
||||
default: 'text',
|
||||
validator: (value: string) => ['text', 'password'].includes(value)
|
||||
},
|
||||
disabled: {
|
||||
// 禁用
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showPasswordOn: {
|
||||
// 查看密码的事件
|
||||
type: String,
|
||||
default: 'click',
|
||||
validator: (value: string) => ['click', 'mouseDown'].includes(value)
|
||||
},
|
||||
})
|
||||
const emit = defineEmits([
|
||||
'update:modelValue', // v-model 必须
|
||||
'focus', // 聚焦事件
|
||||
'blur' // 失焦事件
|
||||
])
|
||||
const inputRef = ref(null)
|
||||
const clear = ref(props.clear)
|
||||
const type = ref(props.type)
|
||||
const disabled = ref(props.disabled)
|
||||
const showPasswordOn = ref(props.showPasswordOn)
|
||||
watchEffect(() => {
|
||||
clear.value = props.clear;
|
||||
type.value = props.type;
|
||||
disabled.value = props.disabled;
|
||||
showPasswordOn.value = props.showPasswordOn
|
||||
})
|
||||
// 输入事件处理
|
||||
const handleInput = (event) => {
|
||||
emit('update:modelValue', event.target.value)
|
||||
}
|
||||
|
||||
// 聚焦事件透传
|
||||
const handleFocus = (event) => {
|
||||
emit('focus', event)
|
||||
}
|
||||
|
||||
// 失焦事件透传
|
||||
const handleBlur = (event) => {
|
||||
emit('blur', event)
|
||||
}
|
||||
|
||||
// 暴露方法(可选)
|
||||
defineExpose({
|
||||
focus: () => inputRef.value.focus(),
|
||||
blur: () => inputRef.value.blur()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="NiInput" data-prefix="Ni">
|
||||
<div class="before">
|
||||
<slot name="before"></slot>
|
||||
</div>
|
||||
<div class="inputMain">
|
||||
<!-- 透传所有原生属性 v-bind="$attrs" -->
|
||||
<input type="text" ref="inputRef"
|
||||
class="ni-input"
|
||||
:value="modelValue"
|
||||
v-bind="$attrs"
|
||||
@input="handleInput"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"></div>
|
||||
<div class="show-password"></div>
|
||||
<div class="after">
|
||||
<slot name="after"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.NiInput {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
& > div.inputMain {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > input {
|
||||
height: 2rem;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
border: 1px solid var(--Ni-theme-border-color);
|
||||
padding: .2rem .5rem;
|
||||
border-radius: var(--Ni-border-radius);
|
||||
box-sizing: border-box;
|
||||
transition: border 0.3s ease-in-out;
|
||||
font-size: 1rem;
|
||||
font-family: v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
|
||||
&:hover {
|
||||
border-color: var(--Ni-theme-border-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
129
components/Ni/Message.vue
Normal file
129
components/Ni/Message.vue
Normal file
@ -0,0 +1,129 @@
|
||||
<!-- components/MessageContainer.vue -->
|
||||
<script setup>
|
||||
const {messages} = useNiMessage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<teleport to="#teleports">
|
||||
<TransitionGroup name="niMessage" tag="div" class="NiMessage" data-prefix="Ni">
|
||||
<div class="niMessageContent" v-for="msg in messages" :key="msg.id" @mouseenter="msg.pause()"
|
||||
@mouseleave="msg.resume()">
|
||||
<div class="niMessageIcon">
|
||||
<div v-if="msg.messageType == 'log'" class="startMessageIconFont messageLog">
|
||||
<NiLogo/>
|
||||
</div>
|
||||
<div v-else-if="msg.messageType == 'info'" class="startMessageIconFont messageInfo"></div>
|
||||
<div v-else-if="msg.messageType == 'success'" class="startMessageIconFont messageSuccess">
|
||||
</div>
|
||||
<div v-else-if="msg.messageType == 'warning'" class="startMessageIconFont messageWarning">
|
||||
</div>
|
||||
<div v-else-if="msg.messageType == 'error'" class="startMessageIconFont messageError"></div>
|
||||
</div>
|
||||
<div class="niMessageBody">
|
||||
{{ msg.content }}
|
||||
</div>
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 动画
|
||||
.niMessage-enter-active, .niMessage-leave-active {
|
||||
transition: all .5s ease-in-out;
|
||||
}
|
||||
|
||||
.niMessage-enter-from, .niMessage-leave-to {
|
||||
transform: translateY(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.NiMessage {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: column; /* 新消息在上方 */
|
||||
gap: 10px;
|
||||
z-index: 9999;
|
||||
pointer-events: none; /* 容器不阻挡点击 */
|
||||
}
|
||||
|
||||
.niMessageContent {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--Ni-content-padding);
|
||||
transition: all 0.3s;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||
border-radius: var(--Ni-border-radius);
|
||||
background: #fefefe;
|
||||
cursor: pointer;
|
||||
letter-spacing: 1px;
|
||||
pointer-events: auto; /* 单个消息可交互 */
|
||||
max-width: min(1000px, 80vw);
|
||||
& > div.niMessageIcon {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
margin-right: .8rem;
|
||||
|
||||
& > div {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
& > div.messageLog {
|
||||
font-size: 6px;
|
||||
}
|
||||
|
||||
& > div.messageInfo {
|
||||
color: var(--Ni-button-info-bg-default);
|
||||
}
|
||||
|
||||
& > div.messageSuccess {
|
||||
color: var(--Ni-button-success-bg-default);
|
||||
}
|
||||
|
||||
& > div.messageWarning {
|
||||
color: var(--Ni-button-warning-bg-default);
|
||||
}
|
||||
|
||||
& > div.messageError {
|
||||
color: var(--Ni-button-error-bg-default);
|
||||
}
|
||||
}
|
||||
|
||||
& > div.niMessageBody {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 入场动画 */
|
||||
.nimessage-enter-active {
|
||||
animation: slideIn 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* 离场动画 */
|
||||
.nimessage-leave-active {
|
||||
transition: opacity 0.3s ease-out;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.nimessage-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateY(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -80,7 +80,7 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<teleport to="#teleports">
|
||||
<Transition name="NiPopup">
|
||||
<Transition name="NiPopup" data-prefix="Ni">
|
||||
<div
|
||||
v-if="visible"
|
||||
ref="NiPopup"
|
||||
@ -93,7 +93,7 @@ onMounted(() => {
|
||||
<div ref="NiPopupContainer" :style="{ '--width': width + 'px' }" class="NiPopupContainer">
|
||||
<header>
|
||||
<div class="logo"><NiLogo/></div>
|
||||
<div class="title"><slot name="title">标题</slot></div>
|
||||
<div class="title"><slot name="header">标题</slot></div>
|
||||
<div class="closeBar"></div>
|
||||
</header>
|
||||
<div class="headerLine"></div>
|
||||
@ -104,7 +104,9 @@ onMounted(() => {
|
||||
</main>
|
||||
<footer>
|
||||
<div class="button">
|
||||
<div><slot name="footer"/></div>
|
||||
<NiSpace>
|
||||
<slot name="footer"/>
|
||||
</NiSpace>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
@ -138,7 +140,6 @@ onMounted(() => {
|
||||
position: relative;
|
||||
will-change: transform; /* 提前告知浏览器会变化的属性 will-change: transform, opacity; 优化性能*/
|
||||
--width: 600px;
|
||||
aspect-ratio: 1/0.618;
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
width: var(--width);
|
||||
@ -149,6 +150,18 @@ onMounted(() => {
|
||||
background-color: var(--Ni-content-bg-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@media (min-width: 768px){
|
||||
&{
|
||||
aspect-ratio: 1/0.618;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px){
|
||||
&{
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 弹窗头
|
||||
.NiPopupContainer>header{
|
||||
@ -184,6 +197,7 @@ onMounted(() => {
|
||||
user-select: none;
|
||||
color: var(--Ni-theme-color);
|
||||
margin-left: .7rem;
|
||||
font-size: 1.2rem;
|
||||
|
||||
&:before{
|
||||
content: ' ';
|
||||
@ -238,4 +252,5 @@ onMounted(() => {
|
||||
animation-direction: reverse;/* 反向播放时 */
|
||||
}
|
||||
|
||||
|
||||
</style>
|
28
components/Ni/Space.vue
Normal file
28
components/Ni/Space.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
gap: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
const gapWith = ref('1');
|
||||
watch(() => props.gap, (value) => {
|
||||
gapWith.value = value
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="NiSpace" data-prefix="Ni" :style="{ '--width': gapWith + 'rem' }" >
|
||||
<slot/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.NiSpace {
|
||||
position: relative;
|
||||
--NiSpace-gap: 1rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--NiSpace-gap) /* 行和列之间的间距 */
|
||||
}
|
||||
</style>
|
50
composables/useNiMessage.ts
Normal file
50
composables/useNiMessage.ts
Normal file
@ -0,0 +1,50 @@
|
||||
// composables/useMessage.ts
|
||||
interface Message {
|
||||
id: number
|
||||
content: string
|
||||
messageType: string
|
||||
close: () => void
|
||||
pause: () => void
|
||||
resume: () => void
|
||||
}
|
||||
|
||||
const messages = reactive<Message[]>([])
|
||||
|
||||
export const useNiMessage = () => {
|
||||
const createMessage = (content: string, messageType: string) => {
|
||||
const id = Date.now()
|
||||
let timeout: NodeJS.Timeout | null = null
|
||||
|
||||
const close = () => {
|
||||
const index = messages.findIndex(msg => msg.id === id)
|
||||
if (index > -1) messages.splice(index, 1)
|
||||
}
|
||||
|
||||
const startTimer = () => {
|
||||
timeout = setTimeout(close, 3000)
|
||||
}
|
||||
|
||||
const message: Message = {
|
||||
id,
|
||||
content,
|
||||
messageType,
|
||||
close,
|
||||
pause: () => timeout && clearTimeout(timeout),
|
||||
resume: () => startTimer()
|
||||
}
|
||||
|
||||
messages.unshift(message) // 新消息显示在最上方
|
||||
startTimer()
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
return {
|
||||
messages,
|
||||
log: (data: string) => createMessage(data, 'log'),
|
||||
info: (data: string) => createMessage(data, 'info'),
|
||||
warning: (data: string) => createMessage(data, 'warning'),
|
||||
error: (data: string) => createMessage(data, 'error'),
|
||||
success: (data: string) => createMessage(data, 'success'),
|
||||
}
|
||||
}
|
@ -2,10 +2,19 @@
|
||||
// 每次热更新都会执行defineNuxtConfig
|
||||
import {exec} from "node:child_process";
|
||||
import open, {apps} from "open";
|
||||
import type {AddressInfo} from "node:net";
|
||||
|
||||
|
||||
export default defineNuxtConfig({
|
||||
vite: {
|
||||
esbuild: {
|
||||
target: 'esnext' // 或 'es2020'
|
||||
},
|
||||
optimizeDeps: {
|
||||
esbuildOptions: {
|
||||
target: 'esnext'
|
||||
}
|
||||
}
|
||||
},
|
||||
compatibilityDate: '2024-11-01',
|
||||
devtools: {enabled: true},
|
||||
modules: ['@nuxt/eslint'],
|
||||
@ -55,8 +64,9 @@ export default defineNuxtConfig({
|
||||
},
|
||||
},
|
||||
hooks: {
|
||||
'listen': (server) => {
|
||||
startBroswer(server.address())
|
||||
'listen': (server, listener) => {
|
||||
const {address, url} = listener
|
||||
startBroswer(address.address, url)
|
||||
},
|
||||
},
|
||||
runtimeConfig: {
|
||||
@ -105,15 +115,14 @@ export default defineNuxtConfig({
|
||||
})
|
||||
|
||||
// 首次启动浏览器
|
||||
async function startBroswer(address: AddressInfo | string | null) {
|
||||
async function startBroswer(address: string, url: string) {
|
||||
if (!process.env.START) {
|
||||
if (address && typeof address !== 'string') {
|
||||
console.log('Hooks: Listen')
|
||||
const host = address.address === '::' ? 'localhost' : address.address
|
||||
const port = address.port
|
||||
const url = `http://${host}:${port}`;
|
||||
const host = address === '::' ? 'localhost' : address
|
||||
const port = url.split(':')[2]
|
||||
const rrealUrl = `http://${host}:${port}`;
|
||||
console.info(`Listening on ${rrealUrl}`);
|
||||
try {
|
||||
await open(url, {
|
||||
await open(rrealUrl, {
|
||||
app: {
|
||||
name: apps.chrome,
|
||||
arguments: [
|
||||
@ -144,4 +153,3 @@ async function startBroswer(address: AddressInfo | string | null) {
|
||||
process.env.START = String(true)
|
||||
}
|
||||
}
|
||||
}
|
3
package-lock.json
generated
3
package-lock.json
generated
@ -16,6 +16,7 @@
|
||||
"mysql2": "^3.14.0",
|
||||
"nuxt": "^3.16.2",
|
||||
"redis": "^4.7.0",
|
||||
"rfdc": "^1.4.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0",
|
||||
"vueuc": "^0.4.64"
|
||||
@ -14054,7 +14055,7 @@
|
||||
},
|
||||
"node_modules/rfdc": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
|
||||
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
|
@ -23,6 +23,7 @@
|
||||
"mysql2": "^3.14.0",
|
||||
"nuxt": "^3.16.2",
|
||||
"redis": "^4.7.0",
|
||||
"rfdc": "^1.4.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0",
|
||||
"vueuc": "^0.4.64"
|
||||
|
@ -1,4 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import rfdc from "rfdc";
|
||||
import type {blogMenu} from "~/drizzle/schema";
|
||||
const clone = rfdc()
|
||||
const niMessage = useNiMessage()
|
||||
|
||||
definePageMeta({
|
||||
layout: 'home',
|
||||
pageTransition: {
|
||||
@ -6,39 +11,67 @@ definePageMeta({
|
||||
mode: 'out-in',
|
||||
},
|
||||
})
|
||||
// 菜单数据类型
|
||||
type InsertBlogMenu = typeof blogMenu.$inferInsert;
|
||||
// 菜单数据
|
||||
const menuList = ref([]);
|
||||
const originalBlogMenuLis = shallowRef([])
|
||||
const blogMenuPidMap = ref(new Map)
|
||||
const blogMenuList = ref<InsertBlogMenu[]>([]);
|
||||
// blog菜单对象
|
||||
const blogMenuObject = ref<InsertBlogMenu>(null);
|
||||
// 菜单折叠
|
||||
const menuCollapseStatus = ref(true)
|
||||
// blog信息弹窗状态
|
||||
const blogInfoPopupStatus = ref(false)
|
||||
const blogInfoPopupStatus2 = ref(false)
|
||||
|
||||
// 格式化菜单数据
|
||||
const formatBlogMenuListToPidMap = (blogMenuList: Array<InsertBlogMenu>) => {
|
||||
const list = clone(blogMenuList)
|
||||
const pidObj: Record<string, InsertBlogMenu[]> = {};
|
||||
for(const menuItem of list){
|
||||
if(pidObj[menuItem.pid]){
|
||||
pidObj[menuItem.pid].push(menuItem)
|
||||
}else{
|
||||
pidObj[menuItem.pid] = [menuItem]
|
||||
}
|
||||
}
|
||||
Object.keys(pidObj).forEach(key => {
|
||||
blogMenuPidMap.value.set(key, pidObj[key]);
|
||||
})
|
||||
}
|
||||
// 获取blog菜单数据
|
||||
const getMenuListFetch = async () => {
|
||||
const { data, pending, error } = await useFetch('/api/blog/blogMenu');
|
||||
const { data, error } = await useFetch('/api/blog/blogMenu');
|
||||
if (error.value) {
|
||||
consola.error('数据获取失败:', error.value);
|
||||
throw error.value;
|
||||
}
|
||||
menuList.value = data.value?.filter(i => i.pid === '0')
|
||||
originalBlogMenuLis.value = data.value;
|
||||
formatBlogMenuListToPidMap(data.value);
|
||||
blogMenuList.value = blogMenuPidMap.value.get('0')
|
||||
}
|
||||
const sendMessage = async () => {
|
||||
// nMessage.success('??')
|
||||
// 新增blog事件
|
||||
const handleCreateBlogMenuItemEvent = (pid: string) => {
|
||||
blogMenuObject.value = {
|
||||
pid,
|
||||
name: '',
|
||||
desc: ''
|
||||
}
|
||||
const handleCloseBefore = (s) => {
|
||||
consola.info('要关闭啦', s)
|
||||
blogInfoPopupStatus.value = true;
|
||||
}
|
||||
// 确认新增
|
||||
const handleCreateBlogMenuItemAck = async () => {
|
||||
consola.info(blogMenuObject.value)
|
||||
const resd= await $fetch('/api/blog/blogMenu',{
|
||||
method: 'POST',
|
||||
body: blogMenuObject.value
|
||||
});
|
||||
consola.info(resd);
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
setTimeout(() => {
|
||||
loading.value = true
|
||||
}, 5000)
|
||||
|
||||
// SSR运行
|
||||
await getMenuListFetch()
|
||||
onMounted(() => {
|
||||
consola.log(menuList.value)
|
||||
|
||||
consola.log(blogMenuList.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -48,16 +81,16 @@ onMounted(() => {
|
||||
<div class="blogMenuContainer">
|
||||
<header class="contentBox">
|
||||
<div class="title">博客目录</div>
|
||||
<div class="bar add star-blogIconFont awaitShow a11 allCenter"></div>
|
||||
<div class="bar add star-blogIconFont awaitShow a11 allCenter" @click="handleCreateBlogMenuItemEvent('0')"></div>
|
||||
<div class="bar star-blogIconFont awaitShow a11 allCenter" @click="menuCollapseStatus = !menuCollapseStatus"></div>
|
||||
</header>
|
||||
<div class="line"/>
|
||||
<div class="blogMenuContent">
|
||||
<div class="contentBox blogMenuItem" v-for="(item, index) in menuList" :key="item.id">
|
||||
<div class="contentBox blogMenuItem" v-for="(item, index) in blogMenuList" :key="item.id">
|
||||
<div class="addIcon star-blogIconFont a11 allCenter"></div>
|
||||
<div class="text oneLineOverMore">{{item.name}}</div>
|
||||
<div class="text"><div class="oneLineOverMore">{{item.name}}</div></div>
|
||||
<div class="barBox" :class="item.pid === '0' && 'awaistShows'">
|
||||
<div class="star-blogIconFont bar a11 allCenter"></div>
|
||||
<div class="star-blogIconFont bar a11 allCenter" @click="handleCreateBlogMenuItemEvent(item.pid)"></div>
|
||||
<div class="star-blogIconFont bar a11 allCenter"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -72,101 +105,26 @@ onMounted(() => {
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<div @click="blogInfoPopupStatus = !blogInfoPopupStatus">点击</div>
|
||||
<div>默认</div>
|
||||
<div>
|
||||
<NiButton>默认按钮</NiButton>
|
||||
<NiButton type="tertiary">tertiary按钮</NiButton>
|
||||
<NiButton loading type="primary">primary按钮</NiButton>
|
||||
<NiButton strong type="info">info按钮</NiButton>
|
||||
<NiButton loading type="success">success按钮</NiButton>
|
||||
<NiButton type="warning">warning按钮</NiButton>
|
||||
<NiButton type="error">error按钮</NiButton>
|
||||
</div>
|
||||
<div>grade 虚线边框</div>
|
||||
<div>
|
||||
<NiButton>默认按钮</NiButton>
|
||||
<NiButton grade="dotted" type="tertiary">tertiary按钮</NiButton>
|
||||
<NiButton grade="dotted" loading type="primary">primary按钮</NiButton>
|
||||
<NiButton grade="dotted" strong type="info">info按钮</NiButton>
|
||||
<NiButton grade="dotted" loading type="success">success按钮</NiButton>
|
||||
<NiButton grade="dotted" type="warning">warning按钮</NiButton>
|
||||
<NiButton grade="dotted" type="error">error按钮</NiButton>
|
||||
</div>
|
||||
<div>grade 浅色</div>
|
||||
<div>
|
||||
<NiButton>默认按钮</NiButton>
|
||||
<NiButton grade="light" type="tertiary">tertiary按钮</NiButton>
|
||||
<NiButton grade="light" loading type="primary">primary按钮</NiButton>
|
||||
<NiButton grade="light" strong type="info">info按钮</NiButton>
|
||||
<NiButton grade="light" loading type="success">success按钮</NiButton>
|
||||
<NiButton grade="light" type="warning">warning按钮</NiButton>
|
||||
<NiButton grade="light" type="error">error按钮</NiButton>
|
||||
</div>
|
||||
<div>grade halfTransparent</div>
|
||||
<div>
|
||||
<NiButton>默认按钮</NiButton>
|
||||
<NiButton grade="halfTransparent" type="tertiary">tertiary按钮</NiButton>
|
||||
<NiButton grade="halfTransparent" loading type="primary">primary按钮</NiButton>
|
||||
<NiButton grade="halfTransparent" strong type="info">info按钮</NiButton>
|
||||
<NiButton grade="halfTransparent" loading type="success">success按钮</NiButton>
|
||||
<NiButton grade="halfTransparent" type="warning">warning按钮</NiButton>
|
||||
<NiButton grade="halfTransparent" type="error">error按钮</NiButton>
|
||||
</div>
|
||||
<div>grade Transparent</div>
|
||||
<div>
|
||||
<NiButton>默认按钮</NiButton>
|
||||
<NiButton grade="transparent" type="tertiary">tertiary按钮</NiButton>
|
||||
<NiButton grade="transparent" loading type="primary">primary按钮</NiButton>
|
||||
<NiButton grade="transparent" strong type="info">info按钮</NiButton>
|
||||
<NiButton grade="transparent" loading type="success">success按钮</NiButton>
|
||||
<NiButton grade="transparent" type="warning">warning按钮</NiButton>
|
||||
<NiButton grade="transparent" type="error">error按钮</NiButton>
|
||||
</div>
|
||||
<div>disable</div>
|
||||
<div>
|
||||
<NiButton>默认按钮</NiButton>
|
||||
<NiButton disabled type="tertiary">tertiary按钮</NiButton>
|
||||
<NiButton disabled type="primary">primary按钮</NiButton>
|
||||
<NiButton loading disabled type="info">info按钮</NiButton>
|
||||
<NiButton disabled type="success">success按钮</NiButton>
|
||||
<NiButton disabled type="warning">warning按钮</NiButton>
|
||||
<NiButton disabled type="error">error按钮</NiButton>
|
||||
</div>
|
||||
<div>半圆角</div>
|
||||
<div>
|
||||
<NiButton>默认按钮</NiButton>
|
||||
<NiButton angle="round" type="tertiary">tertiary按钮</NiButton>
|
||||
<NiButton angle="round" type="primary">primary按钮</NiButton>
|
||||
<NiButton :loading="loading" angle="round" type="info">info按钮</NiButton>
|
||||
<NiButton angle="round" type="success">success按钮</NiButton>
|
||||
<NiButton angle="round" type="warning">warning按钮</NiButton>
|
||||
<NiButton angle="round" type="error">error按钮</NiButton>
|
||||
</div>
|
||||
<div>圆角</div>
|
||||
<div>
|
||||
<NiButton>A</NiButton>
|
||||
<NiButton angle="circle" type="tertiary">B</NiButton>
|
||||
<NiButton angle="circle" type="primary">C</NiButton>
|
||||
<NiButton :loading="loading" angle="circle" type="info">D</NiButton>
|
||||
<NiButton loading angle="circle" type="success">E</NiButton>
|
||||
<NiButton loading angle="circle" type="warning">F</NiButton>
|
||||
<NiButton angle="circle" type="error">G</NiButton>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
<div class="right"></div>
|
||||
<NiPopup v-model:status="blogInfoPopupStatus" width="900" @handleClose="handleCloseBefore">
|
||||
<div @click="blogInfoPopupStatus2 = true">关闭</div>
|
||||
<NiPopup v-model:status="blogInfoPopupStatus">
|
||||
<template #header>博客菜单</template>
|
||||
<NiForm :data="blogMenuObject">
|
||||
<NiFormItem label="博客名称" name="name" label-width="6">
|
||||
<NiInput v-model="blogMenuObject.name"></NiInput>
|
||||
</NiFormItem>
|
||||
<NiFormItem label="博客描述" name="name" label-width="6">
|
||||
<NiInput v-model="blogMenuObject.desc"></NiInput>
|
||||
</NiFormItem>
|
||||
<div>{{ blogMenuObject.name }}</div>
|
||||
<div>{{ blogMenuObject.desc }}</div>
|
||||
</NiForm>
|
||||
<template #footer>
|
||||
关闭
|
||||
<NiButton @click="blogInfoPopupStatus = false">取消</NiButton>
|
||||
<NiButton type="primary" @click="handleCreateBlogMenuItemAck">确认</NiButton>
|
||||
</template>
|
||||
</NiPopup>
|
||||
<NiPopup v-model:status="blogInfoPopupStatus2">
|
||||
<div @click="blogInfoPopupStatus2 = false">
|
||||
</div>
|
||||
</NiPopup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -274,33 +232,36 @@ onMounted(() => {
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
& > div{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
& > div.addIcon{
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
& > div.text{
|
||||
height: 100%;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
min-width: 0;// 关键
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
& > div.barBox{
|
||||
margin-left: .2rem;
|
||||
height: 0;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
transition: opacity .3s;
|
||||
& > div.bar{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&:hover div.barBox{
|
||||
height: 100% !important;
|
||||
width: auto !important;
|
||||
opacity: 1 !important;
|
||||
& > div.bar{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ const leaveTime = ref(false)
|
||||
// 离开前路由拦截
|
||||
onBeforeRouteLeave((to, from, next) => {
|
||||
leaveTime.value = true
|
||||
consola.error('leave')
|
||||
setTimeout(() => {
|
||||
next(true)
|
||||
}, 1000)
|
||||
|
@ -1,11 +1,19 @@
|
||||
export default defineEventHandler(async event => {
|
||||
const requAuth = event.context.auth
|
||||
const body = await readBody(event)
|
||||
if(!requAuth.isTrue) {
|
||||
// 判断为正常登录
|
||||
throw createError({
|
||||
import {BlogMenuDB} from "~/server/services/blog/blogMenu";
|
||||
import consola from "consola";
|
||||
|
||||
})
|
||||
}
|
||||
return 'Hello blog/blogMenu.post'
|
||||
export default defineEventHandler(async event => {
|
||||
// 获取登录信息
|
||||
const headerAuth = event.context.auth
|
||||
// 获取参数
|
||||
const body = await readBody(event)
|
||||
// 初始化DB
|
||||
body.id = event.context.getId()
|
||||
const blogMenuDB = new BlogMenuDB(event)
|
||||
const resd = await blogMenuDB.insertBlogMenu(body, headerAuth)
|
||||
consola.info(body, resd)
|
||||
// if(!requAuth.isTrue) {
|
||||
// // 判断为正常登录
|
||||
// }
|
||||
|
||||
return resd
|
||||
})
|
||||
|
@ -2,10 +2,11 @@ import consola from "consola";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
// console.log(await event.context.redis.get('SI HI'))
|
||||
consola.info('API')
|
||||
consola.info('API TimeOut')
|
||||
const result = await event.context.redis.get('SI HI');
|
||||
return {
|
||||
'SI HI': result
|
||||
}
|
||||
// consola.info('API')
|
||||
// consola.info('API TimeOut')
|
||||
// const result = await event.context.redis.get('SI HI');
|
||||
// return {
|
||||
// 'SI HI': result
|
||||
// }
|
||||
return 's'
|
||||
})
|
||||
|
@ -2,6 +2,7 @@ import { createClient } from 'redis';
|
||||
import consola from 'consola'
|
||||
|
||||
export default defineNitroPlugin(async (nitroApp) => {
|
||||
return
|
||||
const {redis: config} = useRuntimeConfig()
|
||||
consola.info('Redis ...');
|
||||
const redisConnect = createClient({
|
||||
@ -17,8 +18,8 @@ export default defineNitroPlugin(async (nitroApp) => {
|
||||
});
|
||||
|
||||
redisConnect.on('error', (err) => {
|
||||
console.log(err)
|
||||
consola.error('Redis error: ', err);
|
||||
// console.log(err)
|
||||
// consola.error('Redis error: ', err);
|
||||
});
|
||||
|
||||
// 连接到 Redis
|
||||
|
22
server/plugins/snowflake.ts
Normal file
22
server/plugins/snowflake.ts
Normal file
@ -0,0 +1,22 @@
|
||||
export default defineNitroPlugin(nitroApp => {
|
||||
|
||||
nitroApp.hooks.hook('request', async (event) => {
|
||||
event.context.getId = generateEnhancedId
|
||||
})
|
||||
})
|
||||
const EPOCH = 1609459200000;
|
||||
let sequence = 0;
|
||||
|
||||
function generateEnhancedId(): string {
|
||||
const now = Date.now();
|
||||
const timestamp = now - EPOCH;
|
||||
|
||||
// 10 位序列号(支持 1024 个 ID/ms)
|
||||
sequence = (sequence + 1) % 0x400;
|
||||
|
||||
// 组合成 64 位 ID
|
||||
const high = (timestamp << 14) | sequence;
|
||||
const low = Math.floor(Math.random() * 0x100000000);
|
||||
|
||||
return ((BigInt(high) << 32n) | BigInt(low)).toString();
|
||||
}
|
@ -35,6 +35,6 @@ export class BlogMenuDB {
|
||||
.from(blogMenu)
|
||||
.where(
|
||||
and(eq(blogMenu.createdBy, headerAuth.userId), eq(blogMenu.deleted, 0), headerAuth.isTrue ? undefined : eq(blogMenu.public, 1))
|
||||
).orderBy(asc(blogMenu.sort), desc(blogMenu.createdAt));
|
||||
).orderBy(asc(blogMenu.sort), asc(blogMenu.createdAt));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user