| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- <!-- 操作权限 -->
- <template>
- <div class="app-auth">
- <teleport to="body" v-if="type === 'contextmenu'">
- <div class="app-auth__contextmenu" @contextmenu.prevent.capture @click="closeContextmenu"
- v-show="contextmenuOption.show">
- <ul :style="styles">
- <li :class="item.code" v-for="(item, index) in dataList" :key="index"
- @click.stop="openComponent(item.code)">
- <el-icon v-if="item.icon">
- <component :is="item.icon" />
- </el-icon>
- <span>{{ item.title }}</span>
- </li>
- </ul>
- </div>
- </teleport>
- <div class="app-auth__button" v-else>
- <el-dropdown trigger="click" v-if="type === 'dropdown'">
- <el-button size="small" icon="MoreFilled" round />
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item :class="item.code" v-for="(item, index) in dataList" :key="index"
- :icon="item.icon" @click="openComponent(item.code)">
- {{ item.title }}
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- <ul v-else>
- <li v-for="(item, index) in dataList" :key="index">
- <el-button :class="item.className" :type="item.buttonType" :disabled="item.code === componentId"
- @click="openComponent(item.code)" :link="linkButton">
- <el-icon v-if="item.icon">
- <component :is="item.icon" />
- </el-icon>
- <span v-if="item.title">{{ item.title }}</span>
- </el-button>
- </li>
- </ul>
- </div>
- <component :is="componentMap.get(componentId)" :code="componentId" v-bind="options" @closed="closeComponent"
- v-if="componentId" />
- </div>
- </template>
- <script lang="ts" setup>
- import { onMounted, onUnmounted, shallowRef, PropType, computed, watch } from 'vue'
- import { useMenu } from '@/hooks/menu'
- const emit = defineEmits(['click', 'closed'])
- const props = defineProps({
- code: String,
- // 组件参数
- options: Object,
- // 菜单列表
- menus: Array as PropType<string[]>,
- // 操作类型
- type: {
- type: String as PropType<'button' | 'dropdown' | 'contextmenu'>,
- default: 'button',
- },
- // 右键菜单
- contextmenu: {
- type: Object as PropType<{ show: boolean; clientX: number; clientY: number; }>,
- default: () => ({
- show: false,
- clientX: 0,
- clientY: 0,
- }),
- },
- // 链接按钮
- linkButton: {
- type: Boolean,
- default: false,
- },
- })
- const { componentMap, getAuthButtons } = useMenu(props.code);
- const componentId = shallowRef<string>();
- const contextmenuOption = shallowRef(props.contextmenu);
- const auth = shallowRef<Ermcp.UserRoutes[]>([]);
- // 数据列表
- const dataList = computed(() => {
- const menus = props.menus
- if (menus) {
- if (menus.length) {
- return auth.value.filter((e) => menus.includes(e.code) || menus.includes(e.buttonName));
- }
- return [];
- } else {
- return auth.value;
- }
- })
- // 右键菜单坐标
- const styles = computed(() => {
- const { clientX, clientY } = contextmenuOption.value;
- return {
- left: clientX + 'px',
- top: clientY + 'px',
- }
- })
- // 关闭右键菜单
- const closeContextmenu = () => {
- contextmenuOption.value.show = false;
- }
- // 打开组件
- const openComponent = (code: string) => {
- closeContextmenu();
- componentId.value = code;
- emit('click', code);
- }
- // 关闭组件
- const closeComponent = (isCallback?: boolean) => {
- componentId.value = undefined;
- isCallback && emit('closed');
- }
- watch(() => props.contextmenu, (val) => contextmenuOption.value = val)
- onMounted(() => auth.value = getAuthButtons())
- onUnmounted(() => closeComponent())
- </script>
- <style lang="less">
- @import './index.less';
- </style>
|