123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- <template>
- <div class="actions">
- <span
- v-for="(action, i) in items"
- :class="{ active: equal(current as any, action), disabled: action.disabled }"
- :key="action.key || i"
- @click="emit('update:current', current === action ? null : action)"
- >
- <ui-icon :type="action.icon" class="icon" :tip="action.text" />
- </span>
- </div>
- </template>
- <script lang="ts" setup>
- import { useActive } from "@/hook";
- import { ref, toRaw, watchEffect, onBeforeUnmount, nextTick, watch } from "vue";
- export type ActionsItem<T = any> = {
- icon: string;
- key?: T;
- text: string;
- disabled?: boolean;
- action?: () => (() => void) | void;
- };
- export type ActionsProps = {
- items: ActionsItem[];
- current?: ActionsItem | null;
- single?: boolean;
- };
- const props = defineProps<ActionsProps>();
- const emit = defineEmits<{ (e: "update:current", data: ActionsItem | null): void }>();
- const equal = (a: ActionsItem | null, b: ActionsItem | null) => toRaw(a) === toRaw(b);
- watch(
- () => props.current,
- (current) => {
- if (!current) return;
- if (props.single) {
- emit("update:current", null);
- }
- },
- { immediate: true }
- );
- watch(
- () => props.current,
- (current, p, onCleanup) => {
- if (!current) return;
- const fn = current.action && current.action();
- fn && onCleanup(fn);
- },
- { immediate: true }
- );
- </script>
- <style lang="scss" scoped>
- .actions {
- display: flex;
- gap: 3px;
- background: rgba(27, 27, 28, 0.8);
- box-shadow: inset 0px 0px 0px 2px rgba(255, 255, 255, 0.1);
- border-radius: 4px 4px 4px 4px;
- padding: 4px 10px;
- span {
- flex: 1;
- height: 32px;
- width: 32px;
- border-radius: 4px 4px 4px 4px;
- opacity: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- color: rgba(255, 255, 255, 0.6);
- font-size: 14px;
- cursor: pointer;
- transition: all 0.3s ease;
- .icon {
- font-size: 22px;
- }
- &:hover,
- &.active {
- background: rgba(0, 200, 175, 0.16);
- color: #00c8af;
- }
- }
- }
- </style>
|