update 新增图标选择组件,优化菜单编辑功能

This commit is contained in:
2021-04-25 19:53:39 +08:00
parent eb55b3db27
commit 27e333099b
7 changed files with 204 additions and 35 deletions

View File

@@ -23,5 +23,6 @@
@import './lib/dropdown.less';
@import './lib/tree-layout.less';
@import './lib/authority-view.less';
@import './lib/icon-selector.less';
@import './theme/primary.less';
// @import './lib/font-weight.less';

View File

@@ -0,0 +1,60 @@
@import (reference) '~@/assets/style/extend.less';
.yo-icon-selector {
.ant-drawer-wrapper-body {
display: flex;
flex-direction: column;
}
.ant-drawer-body {
position: relative;
flex: 1 1 100%;
padding: 0;
}
.ant-tabs {
height: 100%;
.ant-tabs-left-content {
position: relative;
height: 100%;
padding: 0;
.ant-tabs-tabpane {
position: absolute;
top: 0;
left: 0;
overflow-y: auto;
width: 100%;
height: 100%;
padding: @padding-lg;
}
}
}
.ant-card {
margin: 0;
}
.ant-card-grid {
width: 25%;
text-align: center;
>span {
font-size: @font-size-sm;
display: block;
margin: @padding-xxs -@padding-lg 0;
white-space: nowrap;
color: fade(@black, 50%);
}
&.yo-icon--selected {
color: @white;
background-color: @primary-color;
>span {
color: fade(@white, 50%);
}
}
}
}

View File

@@ -0,0 +1,32 @@
export default [
{
key: 'directional',
title: '方向性图标',
icons: ['step-backward', 'step-forward', 'fast-backward', 'fast-forward', 'shrink', 'arrows-alt', 'down', 'up', 'left', 'right', 'caret-up', 'caret-down', 'caret-left', 'caret-right', 'up-circle', 'down-circle', 'left-circle', 'right-circle', 'double-right', 'double-left', 'vertical-left', 'vertical-right', 'forward', 'backward', 'rollback', 'enter', 'retweet', 'swap', 'swap-left', 'swap-right', 'arrow-up', 'arrow-down', 'arrow-left', 'arrow-right', 'play-circle', 'up-square', 'down-square', 'left-square', 'right-square', 'login', 'logout', 'menu-fold', 'menu-unfold', 'border-bottom', 'border-horizontal', 'border-inner', 'border-left', 'border-right', 'border-top', 'border-verticle', 'pic-center', 'pic-left', 'pic-right', 'radius-bottomleft', 'radius-bottomright', 'radius-upleft', 'fullscreen', 'fullscreen-exit']
},
{
key: 'suggested',
title: '提示建议性图标',
icons: ['question', 'question-circle', 'plus', 'plus-circle', 'pause', 'pause-circle', 'minus', 'minus-circle', 'plus-square', 'minus-square', 'info', 'info-circle', 'exclamation', 'exclamation-circle', 'close', 'close-circle', 'close-square', 'check', 'check-circle', 'check-square', 'clock-circle', 'warning', 'issues-close', 'stop']
},
{
key: 'editor',
title: '编辑类图标',
icons: ['edit', 'form', 'copy', 'scissor', 'delete', 'snippets', 'diff', 'highlight', 'align-center', 'align-left', 'align-right', 'bg-colors', 'bold', 'italic', 'underline', 'strikethrough', 'redo', 'undo', 'zoom-in', 'zoom-out', 'font-colors', 'font-size', 'line-height', 'column-height', 'dash', 'small-dash', 'sort-ascending', 'sort-descending', 'drag', 'ordered-list', 'radius-setting']
},
{
key: 'data',
title: '数据类图标',
icons: ['area-chart', 'pie-chart', 'bar-chart', 'dot-chart', 'line-chart', 'radar-chart', 'heat-map', 'fall', 'rise', 'stock', 'box-plot', 'fund', 'sliders']
},
{
key: 'brand_logo',
title: '网站通用图标',
icons: ['lock', 'unlock', 'bars', 'book', 'calendar', 'cloud', 'cloud-download', 'code', 'copy', 'credit-card', 'delete', 'desktop', 'download', 'ellipsis', 'file', 'file-text', 'file-unknown', 'file-pdf', 'file-word', 'file-excel', 'file-jpg', 'file-ppt', 'file-markdown', 'file-add', 'folder', 'folder-open', 'folder-add', 'hdd', 'frown', 'meh', 'smile', 'inbox', 'laptop', 'appstore', 'link', 'mail', 'mobile', 'notification', 'paper-clip', 'picture', 'poweroff', 'reload', 'search', 'setting', 'share-alt', 'shopping-cart', 'tablet', 'tag', 'tags', 'to-top', 'upload', 'user', 'video-camera', 'home', 'loading', 'loading-3-quarters', 'cloud-upload', 'star', 'heart', 'environment', 'eye', 'camera', 'save', 'team', 'solution', 'phone', 'filter', 'exception', 'export', 'customer-service', 'qrcode', 'scan', 'like', 'dislike', 'message', 'pay-circle', 'calculator', 'pushpin', 'bulb', 'select', 'switcher', 'rocket', 'bell', 'disconnect', 'database', 'compass', 'barcode', 'hourglass', 'key', 'flag', 'layout', 'printer', 'sound', 'usb', 'skin', 'tool', 'sync', 'wifi', 'car', 'schedule', 'user-add', 'user-delete', 'usergroup-add', 'usergroup-delete', 'man', 'woman', 'shop', 'gift', 'idcard', 'medicine-box', 'red-envelope', 'coffee', 'copyright', 'trademark', 'safety', 'wallet', 'bank', 'trophy', 'contacts', 'global', 'shake', 'api', 'fork', 'dashboard', 'table', 'profile', 'alert', 'audit', 'branches', 'build', 'border', 'crown', 'experiment', 'fire', 'money-collect', 'property-safety', 'read', 'reconciliation', 'rest', 'security-scan', 'insurance', 'interaction', 'safety-certificate', 'project', 'thunderbolt', 'block', 'cluster', 'deployment-unit', 'dollar', 'euro', 'pound', 'file-done', 'file-exclamation', 'file-protect', 'file-search', 'file-sync', 'gateway', 'gold', 'robot', 'shopping']
},
{
key: 'application',
title: '品牌和标识',
icons: ['android', 'apple', 'windows', 'ie', 'chrome', 'github', 'aliwangwang', 'dingding', 'weibo-square', 'weibo-circle', 'taobao-circle', 'html5', 'weibo', 'twitter', 'wechat', 'youtube', 'alipay-circle', 'taobao', 'skype', 'qq', 'medium-workmark', 'gitlab', 'medium', 'linkedin', 'google-plus', 'dropbox', 'facebook', 'codepen', 'code-sandbox', 'amazon', 'google', 'codepen-circle', 'alipay', 'ant-design', 'aliyun', 'zhihu', 'slack', 'slack-square', 'behance', 'behance-square', 'dribbble', 'dribbble-square', 'instagram', 'yuque', 'alibaba', 'yahoo']
}
]

View File

@@ -0,0 +1,63 @@
<template>
<a-drawer :visible="visible" @close="onClose" class="yo-icon-selector" title="选择图标" width="600">
<a-tabs tab-position="left" v-model="active">
<a-tab-pane :key="iconGroup.key" :tab="iconGroup.title" v-for="iconGroup in icons">
<a-card>
<a-card-grid
:class="{ 'yo-icon--selected': selected == icon }"
:key="icon"
@click="onSelectIcon(icon)"
v-for="icon in iconGroup.icons"
>
<a-icon :style="{ fontSize: '36px' }" :type="icon" />
<span>{{ icon }}</span>
</a-card-grid>
</a-card>
</a-tab-pane>
</a-tabs>
</a-drawer>
</template>
<script>
import icons from './icons';
export default {
model: {
prop: 'selected',
event: 'select',
},
props: {
selected: {
type: String,
},
},
data() {
return {
visible: false,
icons,
active: icons[0].key,
};
},
methods: {
onOpen() {
this.visible = true;
if (this.selected) {
this.active = (icons.find((p) => p.icons.indexOf(this.selected) > -1) || icons[0]).key;
} else {
this.active = icons[0].key;
}
},
onClose() {
this.visible = false;
},
onSelectIcon(icon) {
this.$emit('select', icon);
this.onClose();
},
},
};
</script>

View File

@@ -41,11 +41,11 @@ export default {
* 必要的方法
* 从外部调用打开本窗口
*/
async onOpen() {
async onOpen(record) {
this.visible = true;
this.$nextTick(() => {
this.formBody.onInit();
this.$nextTick(async () => {
await this.formBody.onInit(record, true);
});
},

View File

@@ -31,11 +31,7 @@
<a-input placeholder="请输入唯一编码" v-model="form.code" />
</a-form-model-item>
<a-form-model-item label="所属应用" prop="application">
<a-select
@change="onChangeApplication"
placeholder="请选择所属应用"
v-model="form.application"
>
<a-select @change="onLoadMenuTree" placeholder="请选择所属应用" v-model="form.application">
<a-select-option
:key="item.code"
:value="item.code"
@@ -99,7 +95,12 @@
<a-switch checked-children="可见" un-checked-children="隐藏" v-model="form.visible" />
</a-form-model-item>
<!-- 图标只有[按钮]不可用 -->
<a-form-model-item label="图标" v-if="form.type != 2"></a-form-model-item>
<a-form-model-item label="图标" v-if="form.type != 2">
<a-input :disabled="true" placeholder="请选择图标" v-model="form.icon">
<a-icon :type="form.icon" slot="addonBefore" v-if="form.icon" />
<a-icon @click="onOpenSelectIcon" slot="addonAfter" type="setting" />
</a-input>
</a-form-model-item>
<a-form-model-item label="排序">
<a-input-number
:max="1000"
@@ -115,11 +116,15 @@
</div>
</div>
</a-spin>
<yo-icon-selector ref="icon-selector" v-model="form.icon" />
</a-form-model>
</template>
<script>
import { EMPTY_ID } from '@/util/global';
import YoIconSelector from '@/components/yoIconSelector';
const defaultValue = {
type: '1',
openType: '1',
@@ -129,6 +134,10 @@ const defaultValue = {
};
export default {
components: {
YoIconSelector,
},
data() {
return {
/** 表单数据 */
@@ -227,7 +236,7 @@ export default {
* 必要方法
* 加载当前表单中所需要的异步数据
*/
async onInit(record) {
async onInit(record, isParent = false) {
this.loading = true;
/** 可以在这里await获取一些异步数据 */
@@ -235,17 +244,12 @@ export default {
this.codes = await this.onLoadCodes();
this.appList = await this.onLoadSysApplist();
if (record) {
const treeData = await this.onLoadMenuTree(record.application);
this.parentTreeData = [
{
id: EMPTY_ID,
parentId: undefined,
title: '顶级',
value: EMPTY_ID,
pid: undefined,
children: treeData,
},
];
await this.onLoadMenuTree(record.application);
if (isParent) {
this.$set(this.form, 'pid', record.id);
this.$set(this.form, 'application', record.application);
}
}
/** ...END */
this.loading = false;
@@ -277,7 +281,16 @@ export default {
onLoadMenuTree(app) {
return this.$api.getMenuTree({ application: app }).then(({ data }) => {
return data;
this.parentTreeData = [
{
id: EMPTY_ID,
parentId: undefined,
title: '顶级',
value: EMPTY_ID,
pid: undefined,
children: data,
},
];
});
},
@@ -304,19 +317,12 @@ export default {
this.onTypeChangeGroup();
},
onChangeApplication(value) {
this.onLoadMenuTree(value).then((data) => {
this.parentTreeData = [
{
id: EMPTY_ID,
parentId: undefined,
title: '顶级',
value: EMPTY_ID,
pid: undefined,
children: data,
onOpenSelectIcon() {
this.$refs['icon-selector'].onOpen(this.form.icon);
},
];
});
onSelectIcon(icon) {
this.$set(this.form, 'icon', icon);
},
},
};

View File

@@ -1,5 +1,9 @@
<template>
<container>
<br />
<a-alert type="error">
<template slot="message">按钮编辑关闭时调用resetFields报错,原因为visible=undefined</template>
</a-alert>
<br />
<a-card :bordered="false">
<yo-table :columns="columns" :load-data="loadData" ref="table">
@@ -14,6 +18,9 @@
</span>
<span slot="action" slot-scope="text, record">
<yo-table-actions>
<Auth auth="sysMenu:add" v-if="record.type < 2">
<a @click="onOpen('add-form', record)">新增子菜单</a>
</Auth>
<Auth auth="sysMenu:edit">
<a @click="onOpen('edit-form', record)">编辑</a>
</Auth>