mirror of
https://gitee.com/chu1204505056/vue-admin-beautiful.git
synced 2025-04-06 03:58:00 +08:00
✨1.优化手机端显示效果 2.添加图标组件
This commit is contained in:
parent
16e69e181e
commit
2cf2fe21b2
2294
mock/controller/icon.js
Normal file
2294
mock/controller/icon.js
Normal file
File diff suppressed because it is too large
Load Diff
9
src/api/icon.js
Normal file
9
src/api/icon.js
Normal file
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getIconList(params) {
|
||||
return request({
|
||||
url: '/icon/getList',
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
@ -6,15 +6,16 @@
|
||||
@click="handleFoldSideBar"
|
||||
></div>
|
||||
<a-layout-sider
|
||||
collapsible
|
||||
class="vab-sider"
|
||||
width="250"
|
||||
v-model:collapsed="collapse"
|
||||
:trigger="null"
|
||||
collapsible
|
||||
:class="classObj"
|
||||
:trigger="null"
|
||||
>
|
||||
<vab-logo />
|
||||
<a-menu
|
||||
class="menu"
|
||||
class="vab-menu"
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
@ -22,8 +23,11 @@
|
||||
<vab-menu v-for="route in routes" :key="route.path" :item="route" />
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<a-layout>
|
||||
<a-layout-header class="header">
|
||||
<a-layout
|
||||
class="vab-layout"
|
||||
:class="'mobile' === device ? 'vab-mobile-layout' : ''"
|
||||
>
|
||||
<a-layout-header class="vab-header">
|
||||
<a-row>
|
||||
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<menu-unfold-outlined
|
||||
@ -122,72 +126,83 @@
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.ant-layout-content {
|
||||
min-height: calc(
|
||||
100vh - @vab-header-height - @vab-padding - @vab-padding - @vab-padding -
|
||||
@vab-padding
|
||||
) !important;
|
||||
}
|
||||
.ant-layout-sider-collapsed {
|
||||
.vab-logo .anticon + span {
|
||||
display: inline-block;
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
|
||||
width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
}
|
||||
}
|
||||
.header {
|
||||
.ant-col + .ant-col {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 0 @vab-padding;
|
||||
}
|
||||
}
|
||||
.vab-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 998;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.vab-mobile {
|
||||
position: fixed !important;
|
||||
z-index: 999;
|
||||
}
|
||||
.vab-mobile.vab-collapse {
|
||||
width: 0 !important;
|
||||
min-width: 0 !important;
|
||||
max-width: 0 !important;
|
||||
* {
|
||||
display: none !important;
|
||||
width: 0 !important;
|
||||
min-width: 0 !important;
|
||||
max-width: 0 !important;
|
||||
}
|
||||
.ant-menu-item,
|
||||
.ant-menu-submenu {
|
||||
display: none !important;
|
||||
width: 0 !important;
|
||||
min-width: 0 !important;
|
||||
max-width: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scpoed>
|
||||
.vab-layout-wrap {
|
||||
.menu {
|
||||
height: calc(100vh - @vab-header-height);
|
||||
.vab-sider {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
.vab-menu {
|
||||
height: calc(100vh - @vab-header-height);
|
||||
}
|
||||
}
|
||||
.header {
|
||||
.vab-layout {
|
||||
padding-left: 250px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.vab-mobile-layout {
|
||||
padding-left: 0;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.vab-collapse {
|
||||
.vab-logo .anticon + span {
|
||||
display: inline-block;
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
& + .vab-layout {
|
||||
padding-left: 81px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
}
|
||||
.vab-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 998;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.vab-mobile {
|
||||
position: fixed !important;
|
||||
z-index: 999;
|
||||
&.vab-collapse {
|
||||
width: 0 !important;
|
||||
min-width: 0 !important;
|
||||
max-width: 0 !important;
|
||||
* {
|
||||
display: none !important;
|
||||
width: 0 !important;
|
||||
min-width: 0 !important;
|
||||
max-width: 0 !important;
|
||||
}
|
||||
.ant-menu-item,
|
||||
.ant-menu-submenu {
|
||||
display: none !important;
|
||||
width: 0 !important;
|
||||
min-width: 0 !important;
|
||||
max-width: 0 !important;
|
||||
}
|
||||
& + .vab-layout {
|
||||
padding-left: 0px !important;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
}
|
||||
}
|
||||
.vab-header {
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
.ant-col + .ant-col {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 0 @vab-padding;
|
||||
}
|
||||
.trigger {
|
||||
height: @vab-header-height;
|
||||
padding: 0 @vab-padding;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-layout-content class="content">
|
||||
<a-layout-content class="vab-content">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition mode="out-in" name="fade-transform">
|
||||
<component :is="Component" />
|
||||
@ -40,7 +40,11 @@
|
||||
transform: translateX(30px);
|
||||
}
|
||||
|
||||
.content {
|
||||
.vab-content {
|
||||
min-height: calc(
|
||||
100vh - @vab-header-height - @vab-padding - @vab-padding - @vab-padding -
|
||||
@vab-padding
|
||||
) !important;
|
||||
padding: @vab-padding;
|
||||
margin: @vab-margin;
|
||||
background: #fff;
|
||||
|
@ -62,6 +62,15 @@ export const asyncRoutes = [
|
||||
icon: 'table-2',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'icon',
|
||||
name: 'Icon',
|
||||
component: () => import('@/views/vab/icon'),
|
||||
meta: {
|
||||
title: '图标',
|
||||
icon: 'remixicon-line',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
30
src/utils/clipboard.js
Normal file
30
src/utils/clipboard.js
Normal file
@ -0,0 +1,30 @@
|
||||
import Clipboard from 'clipboard'
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
function clipboardSuccess(text) {
|
||||
message.success(`复制${text}成功`)
|
||||
}
|
||||
|
||||
function clipboardError(text) {
|
||||
message.error(`复制${text}失败`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 复制数据
|
||||
* @param text
|
||||
* @param event
|
||||
*/
|
||||
export default function handleClipboard(text, event) {
|
||||
const clipboard = new Clipboard(event.target, {
|
||||
text: () => text,
|
||||
})
|
||||
clipboard.on('success', () => {
|
||||
clipboardSuccess(text)
|
||||
clipboard.destroy()
|
||||
})
|
||||
clipboard.on('error', () => {
|
||||
clipboardError(text)
|
||||
clipboard.destroy()
|
||||
})
|
||||
clipboard.onClick(event)
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
@import "./normalize.less";
|
||||
|
||||
/* 滚动条样式 */
|
||||
.base-scrollbar {
|
||||
&::-webkit-scrollbar {
|
||||
@ -25,5 +26,24 @@ html {
|
||||
box-sizing: border-box;
|
||||
.base-scrollbar;
|
||||
}
|
||||
|
||||
/* ant-input-search搜索框 */
|
||||
.ant-input-search {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
/* ant-pagination分页 */
|
||||
.ant-pagination {
|
||||
margin-top: @vab-margin;
|
||||
text-align: center;
|
||||
|
||||
&.ant-table-pagination {
|
||||
float: none !important;
|
||||
margin-top: @vab-margin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<a-row>
|
||||
<a-col :xs="24" :md="11" :sm="24" :lg="14" :xl="14"></a-col>
|
||||
<a-col :xs="24" :sm="24" :md="12" :lg="9" :xl="6">
|
||||
<a-col :xs="0" :md="0" :sm="12" :lg="14" :xl="16"></a-col>
|
||||
<a-col :xs="24" :sm="24" :md="12" :lg="10" :xl="6">
|
||||
<div class="login-container-form">
|
||||
<div class="login-container-hello">hello!</div>
|
||||
<div class="login-container-title">欢迎来到 {{ title }}</div>
|
||||
@ -37,7 +37,6 @@
|
||||
</a-form>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :xs="24" :md="11" :sm="24" :lg="14" :xl="14"></a-col>
|
||||
</a-row>
|
||||
<div class="login-container-tips">
|
||||
基于vue{{ dependencies['vue'] }}
|
||||
@ -87,7 +86,7 @@
|
||||
this.form.password = '123456'
|
||||
setTimeout(() => {
|
||||
this.handleSubmit()
|
||||
}, 500000)
|
||||
}, 5000)
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
|
129
src/views/vab/icon/index.vue
Normal file
129
src/views/vab/icon/index.vue
Normal file
@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="icon-container">
|
||||
<a-alert message="点击图标即可复制代码" type="success" show-icon></a-alert>
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="24">
|
||||
<a-input-search
|
||||
v-model:value="queryForm.title"
|
||||
placeholder="图标名称"
|
||||
enter-button
|
||||
@search="queryData"
|
||||
/>
|
||||
</a-col>
|
||||
|
||||
<a-col
|
||||
v-for="(item, index) in queryIcon"
|
||||
:key="index"
|
||||
:lg="2"
|
||||
:md="3"
|
||||
:sm="8"
|
||||
:xl="2"
|
||||
:xs="6"
|
||||
>
|
||||
<a-card shadow="hover" @click="handleCopyIcon(item, $event)">
|
||||
<vab-icon :icon="item"></vab-icon>
|
||||
</a-card>
|
||||
<div class="icon-text" @click="handleCopyText(item, $event)">
|
||||
{{ item }}
|
||||
</div>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="24">
|
||||
<a-pagination
|
||||
show-quick-jumper
|
||||
v-model:current="queryForm.current"
|
||||
:total="total"
|
||||
@change="handleCurrentChange"
|
||||
@showSizeChange="handlePageSizeChange"
|
||||
/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getIconList } from '@/api/icon'
|
||||
import clip from '@/utils/clipboard'
|
||||
import VabIcon from '@/layout/vab-icon'
|
||||
|
||||
export default {
|
||||
name: 'Icon',
|
||||
components: { VabIcon },
|
||||
data() {
|
||||
return {
|
||||
total: 0,
|
||||
queryIcon: [],
|
||||
queryForm: {
|
||||
current: 1,
|
||||
pageSize: 72,
|
||||
title: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
handlePageSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.current = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.current = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
const { data, totalCount } = await getIconList(this.queryForm)
|
||||
this.queryIcon = data
|
||||
this.total = totalCount
|
||||
},
|
||||
handleCopyText(item, event) {
|
||||
clip(item, event)
|
||||
},
|
||||
handleCopyIcon(item, event) {
|
||||
clip(`<vab-remix-icon icon-class="${item}"></vab-remix-icon>`, event)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.icon-container {
|
||||
::v-deep {
|
||||
.ant-input-search,
|
||||
.ant-alert {
|
||||
margin-bottom: @vab-padding;
|
||||
}
|
||||
.ant-card-body {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 68px;
|
||||
cursor: pointer;
|
||||
|
||||
i {
|
||||
font-size: 28px;
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
height: 30px;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user