图标选择控件

This commit is contained in:
gary.fu
2024-01-02 14:07:17 +08:00
parent 6cd17a6702
commit 4a68e5fbc5
19 changed files with 343 additions and 77 deletions

View File

@@ -16,6 +16,7 @@ import ControlChild from '@/components/common-form-control/control-child.vue'
* @property {boolean} required 是否必填,后面解析成为rules的一部分
* @property {string|RegExp} pattern 正则表达式验证解析成为rules的一部分
* @property {string} patternMsg 正则表达式验证消息
* @property {boolean} common 自定义组件
* @property {boolean} disabled 禁用
* @property {boolean} readonly 只读
* @property {string} placeholder 占位提示符
@@ -41,6 +42,9 @@ const props = defineProps({
})
const inputType = computed(() => {
if (props.option.common) {
return `common-${props.option.type}`
}
return `el-${props.option.type || 'input'}`
})

View File

@@ -0,0 +1,167 @@
<script setup>
import { computed, ref } from 'vue'
import { filterIconsByKeywords } from '@/services/icon/IconService'
import { useVModel } from '@vueuse/core'
const props = defineProps({
modelValue: {
type: String,
default: ''
},
dialogAttrs: {
type: Object,
default () {
return {}
}
},
colSize: {
type: Number,
default: 6
},
dialogHeight: {
type: String,
default: '400px'
},
dialogWidth: {
type: String,
default: '600px'
},
disabled: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: ''
}
})
const iconSelectVisible = ref(false)
const keyWords = ref('')
const filterIcons = computed(() => {
if (iconSelectVisible.value) {
return filterIconsByKeywords(keyWords.value, props.colSize)
}
return []
})
const emit = defineEmits(['update:modelValue'])
const vModel = useVModel(props, 'modelValue', emit)
const selectIcon = icon => {
iconSelectVisible.value = false
vModel.value = icon
}
</script>
<template>
<label class="el-radio">
<common-icon
v-if="modelValue"
:icon="modelValue"
class="el-radio__input"
/>
<span
v-if="modelValue"
class="el-radio__label"
>{{ modelValue }}</span>
<el-button
class="icon-select-button"
type="primary"
:disabled="disabled||readonly"
size="small"
@click="iconSelectVisible = true"
>
{{ $t('common.label.select') }}
</el-button>
</label>
<el-button
v-if="vModel"
type="danger"
:disabled="disabled||readonly"
size="small"
@click="vModel = ''"
>
{{ $t('common.label.clear') }}
</el-button>
<el-dialog
v-model="iconSelectVisible"
:width="dialogWidth"
v-bind="dialogAttrs"
draggable
class="icon-dialog"
:title="$t('common.msg.pleaseSelectIcon')"
>
<el-container
style="overflow: auto;"
:style="{ height: dialogHeight }"
class="icon-container"
>
<el-header height="40px">
<el-form label-width="120px">
<el-form-item :label="$t('common.label.keywords')">
<el-input
v-model="keyWords"
:placeholder="$t('common.msg.inputKeywords')"
/>
</el-form-item>
</el-form>
</el-header>
<el-main>
<RecycleScroller
v-slot="{ item }"
class="scroller icon-list"
:items="filterIcons"
:item-size="80"
key-field="id"
>
<el-row>
<el-col
v-for="icon in item.icons"
:key="icon"
:span="24/colSize"
class="text-center"
>
<a
class="el-button el-button--large is-text"
style="height:80px;"
@click="selectIcon(icon)"
>
<div>
<common-icon
size="20"
:icon="icon"
/>
</div>
</a>
</el-col>
</el-row>
</RecycleScroller>
</el-main>
</el-container>
</el-dialog>
</template>
<style scoped>
.scroller {
height: 100%;
}
.icon-container {
overflow: auto;
}
.icon-container .el-input {
width: 80%;
}
.icon-select-button {
margin-left: 10px;
}
.el-radio {
margin-right: 10px;
}
</style>

View File

@@ -27,7 +27,7 @@ const props = defineProps({
required: true
},
/**
* @type {'large'|'small'|'default'}
* @type {''|'large'|'small'|'default'}
*/
buttonSize: {
type: String,
@@ -75,19 +75,21 @@ const props = defineProps({
<template
#default="scope"
>
<el-button
v-for="(button, index) in column.buttons"
:key="index"
:type="button.type"
:icon="button.icon"
:size="button.size||buttonSize"
:disabled="button.disabled"
:round="button.round"
:circle="button.circle"
@click="button.click&&button.click(scope.row, scope)"
>
{{ button.label || $t(button.labelKey) }}
</el-button>
<template v-for="(button, index) in column.buttons">
<el-button
v-if="!button.buttonIf||button.buttonIf(scope.row, scope)"
:key="index"
:type="button.type"
:icon="button.icon"
:size="button.size||buttonSize"
:disabled="button.disabled"
:round="button.round"
:circle="button.circle"
@click="button.click&&button.click(scope.row, scope)"
>
{{ button.label || $t(button.labelKey) }}
</el-button>
</template>
<slot
name="default"
v-bind="scope"

View File

@@ -92,10 +92,7 @@ const onDropdownVisibleChange = (visible, tab) => {
</template>
<style scoped>
.common-tabs > .el-tabs__content {
padding: 32px;
color: #6b778c;
font-size: 32px;
font-weight: 600;
.common-tabs .el-tabs__header {
margin: 0;
}
</style>

View File

@@ -1,4 +1,5 @@
import CommonIcon from '@/components/common-icon/index.vue'
import CommonIconSelect from '@/components/common-icon-select/index.vue'
import CommonForm from '@/components/common-form/index.vue'
import CommonFormControl from '@/components/common-form-control/index.vue'
import CommonMenu from '@/components/common-menu/index.vue'
@@ -15,6 +16,7 @@ export default {
*/
install (Vue) {
Vue.component('CommonIcon', CommonIcon)
Vue.component('CommonIconSelect', CommonIconSelect)
Vue.component('CommonForm', CommonForm)
Vue.component('CommonFormControl', CommonFormControl)
Vue.component('CommonMenu', CommonMenu)