feat:组件二次封装

main
向文可 2 years ago
parent 7a03f1fd4e
commit 7160ed97ac

@ -11,7 +11,8 @@
},
});
const slots = useSlots();
const render = () => <ElCascader {...props} v-slots={slots} />;
const attrs = useAttrs();
const render = () => <ElCascader {...props} {...attrs} v-slots={slots} />;
</script>
<style lang="less" scoped></style>

@ -0,0 +1,61 @@
<template>
<component :is="render" />
</template>
<script setup lang="jsx">
import { ElCheckboxGroup } from 'element-plus/es/components/checkbox/index';
import 'element-plus/es/components/checkbox/style/css';
const props = defineProps({
opts: {
type: Array,
required: true,
},
config: {
type: Object,
default() {
return {
label: 'label',
value: 'value',
disabled: 'disabled',
};
},
},
button: {
type: Boolean,
default: false,
},
});
const slots = useSlots();
const attrs = useAttrs();
let config = {
label: 'label',
value: 'value',
disabled: 'disabled',
...props.config,
};
function handleItemDisabled(item, index) {
let res = false;
if (config.disabled instanceof Function) {
res = config.disabled(item, index);
} else {
res = !!item[config.disabled];
}
return res;
}
const render = () => (
<ElCheckboxGroup
{...props}
{...attrs}
v-slots={{
default: () =>
props.opts.map((item, index) => (
<ElCheckbox label={item[config.value]} disabled={handleItemDisabled(item, index)}>
{item[config.label]}
</ElCheckbox>
)),
...slots,
}}
></ElCheckboxGroup>
);
</script>
<style lang="less" scoped></style>

@ -0,0 +1,85 @@
<template>
<component :is="render" />
</template>
<script setup lang="jsx">
import { ElDialog } from 'element-plus/es/components/dialog/index';
import 'element-plus/es/components/dialog/style/css';
const props = defineProps({
destroyOnClose: {
type: Boolean,
default: true,
},
draggable: {
type: Boolean,
default: true,
},
closeOnClickModal: {
type: Boolean,
default: false,
},
closeOnPressEscape: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['update:fullscreen']);
const slots = useSlots();
const attrs = useAttrs();
const fullscreen = ref(attrs.fullscreen || false);
const handleFullScreen = () => {
fullscreen.value = !unref(fullscreen);
emit('update:fullscreen', unref(fullscreen));
};
const dialogSlots = {
...slots,
title() {
return (
<div class="el-dialog__header-wrapper">
{slots.title?.() || <span class="el-dialog__title">{attrs.title || '弹窗'}</span>}
<ElButton
aria-label="fullscreen"
class="el-dialog__headerbtn fullscreen-btn"
type="text"
onClick={() => handleFullScreen()}
>
<ElIcon class="el-dialog__fullscreen" name={unref(fullscreen) ? 'Minus' : 'FullScreen'} />
</ElButton>
</div>
);
},
};
const render = () => <ElDialog {...props} {...attrs} fullscreen={unref(fullscreen)} v-slots={dialogSlots} />;
</script>
<style lang="less">
.el-dialog {
&.is-fullscreen {
display: flex;
flex-direction: column;
.el-dialog__body {
flex: 1;
}
}
.el-dialog__header {
padding: @layout-space-large;
.el-dialog__header-wrapper {
display: flex;
justify-content: space-between;
.fullscreen-btn {
position: static;
height: auto;
color: var(--el-button-text-color, var(--el-text-color-regular));
:hover {
color: var(--el-color-primary);
}
}
}
}
.el-dialog__body {
padding: @layout-space-large;
}
.el-dialog__headerbtn {
top: calc(@layout-space-large + 5px);
height: auto;
}
}
</style>

@ -0,0 +1,63 @@
<template>
<component :is="render" />
</template>
<script setup lang="jsx">
import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus/es/components/dropdown/index';
import 'element-plus/es/components/dropdown/style/css';
const props = defineProps({
type: {
type: String,
default: 'text',
},
icon: {
type: String,
default: 'ArrowDown',
},
size: {
type: String,
default: 'middle',
},
splitButton: {
type: Boolean,
default: false,
},
opts: {
type: Array,
required: true,
},
});
const attrs = useAttrs();
const slots = useSlots();
const handleCommand = (index) => {
props.opts[index].onClick?.();
};
const dropdownSlots = {
dropdown: () => (
<ElDropdownMenu>
{(props.opts || []).map((item, index) => (
<ElDropdownItem command={index} disabled={item.disabled} divided={item.divided}>
{item.label}
</ElDropdownItem>
))}
</ElDropdownMenu>
),
default: () => (
<ElButton type="text">
{slots.default?.() || '更多'}
<ElIcon name={props.icon} size="16" />
</ElButton>
),
};
const render = () => (
<ElDropdown {...props} {...attrs} onCommand={(command) => handleCommand(command)} v-slots={dropdownSlots} />
);
</script>
<style lang="less" scoped>
.el-dropdown {
:deep(.x-icon) {
top: 0;
margin-left: @layout-space-small;
}
}
</style>

@ -47,7 +47,6 @@
font-size: v-bind(size);
color: v-bind(color);
line-height: 1;
vertical-align: middle;
position: relative;
top: 1px;
}

@ -29,6 +29,7 @@
},
});
const slots = useSlots();
const attrs = useAttrs();
let config = {
label: 'label',
value: 'value',
@ -52,6 +53,7 @@
const render = () => (
<ElSelect
{...props}
{...attrs}
v-slots={{
default: () =>
unref(opts).map((item, index) => (

@ -1,17 +1,8 @@
<template>
<div class="layout-profile">
<el-avatar :src="userInfo?.avatar" />
<el-dropdown size="middle" @command="handleCommand">
<span class="el-dropdown-link">
<span>{{ userInfo?.nickname || userInfo?.username }}</span>
<el-icon class="el-icon--right" name="ArrowDown" />
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
<el-dropdown :opts="opts">
<span>{{ userInfo?.nickname || userInfo?.username }}</span>
</el-dropdown>
</div>
</template>
@ -19,13 +10,20 @@
<script setup>
const store = useStore();
const userInfo = computed(() => store.state.auth.userInfo);
const handleCommand = (command) => {
switch (command) {
case 'logout':
const opts = reactive([
{
label: '个人中心',
onClick() {
alert('个人中心');
},
},
{
label: '退出登录',
onClick() {
store.dispatch('auth/logout');
break;
}
};
},
},
]);
</script>
<style lang="less" scoped>

@ -15,16 +15,8 @@
</el-tab-pane>
</el-tabs>
<div class="operation">
<el-dropdown trigger="hover" @command="handleCommand">
<span class="el-dropdown-link">
<el-icon name="apps-fill" />
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="all">关闭全部</el-dropdown-item>
<el-dropdown-item command="other">关闭其他</el-dropdown-item>
</el-dropdown-menu>
</template>
<el-dropdown trigger="hover" :opts="opts" icon="apps-fill">
<span></span>
</el-dropdown>
</div>
</div>
@ -53,19 +45,23 @@
const handleClick = (tab) => {
router.push(unref(tabList)[tab.index].fullPath);
};
const handleCommand = (command) => {
switch (command) {
case 'all':
const opts = reactive([
{
label: '关闭全部',
onClick() {
store.commit('layout/closeTab', {});
break;
case 'other':
},
},
{
label: '关闭其他',
onClick() {
store.commit('layout/closeTab', {
index: unref(tabList).findIndex((item) => item.name === unref(activeTab)),
reverse: true,
});
break;
}
};
},
},
]);
</script>
<style lang="less" scoped>

@ -1,16 +1,12 @@
<template>
<div class="container">
<el-select
:opts="[
{ label: '女', value: 0 },
{ label: '男', value: 1 },
]"
></el-select>
<el-cascader></el-cascader>
<el-dialog center :model-value="true">
<el-select :opts="opts"></el-select>
<el-cascader :options="opts" @change="handleAdd"></el-cascader>
<el-checkbox-group :opts="opts"></el-checkbox-group>
<el-dropdown :opts="opts2"></el-dropdown>
</el-dialog>
<h1>{{ $route.name }}</h1>
<h1>TOKEN:{{ token }}</h1>
<h2>{{ userInfo }}</h2>
<h4>{{ permission }}</h4>
<h1>
<el-icon name="app-store" size="30" />
<span>马士兵严选</span>
@ -42,6 +38,24 @@
store.dispatch('demo/clear');
};
const form = reactive({ msg: '123' });
const opts = reactive([
{ label: '男', value: 1 },
{ label: '女', value: 0 },
]);
const opts2 = reactive([
{
label: '编辑',
onClick() {
alert('编辑');
},
},
{
label: '删除',
onClick() {
alert('删除');
},
},
]);
</script>
<style lang="less" scoped>

Loading…
Cancel
Save