158 lines
3.8 KiB
Vue
158 lines
3.8 KiB
Vue
<template>
|
|
<ElDialog
|
|
v-model="visible"
|
|
title="设置限速"
|
|
width="500px"
|
|
:lock-scroll="true"
|
|
:z-index="4000"
|
|
modal-class="speed-limit-modal"
|
|
>
|
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
|
<ElFormItem label="固定档位" prop="code">
|
|
<ElSelect
|
|
v-model="form.code"
|
|
placeholder="请选择限速档位"
|
|
style="width: 100%"
|
|
:teleported="true"
|
|
append-to="body"
|
|
popper-class="speed-limit-select-popper"
|
|
:popper-style="{ zIndex: 4001 }"
|
|
>
|
|
<ElOption
|
|
v-for="tier in speedTiers"
|
|
:key="tier.code"
|
|
:label="tier.label"
|
|
:value="tier.code"
|
|
/>
|
|
</ElSelect>
|
|
</ElFormItem>
|
|
</ElForm>
|
|
<template #footer>
|
|
<ElButton @click="handleCancel">取消</ElButton>
|
|
<ElButton
|
|
type="primary"
|
|
@click="handleConfirm"
|
|
:loading="confirmLoading"
|
|
:disabled="confirmLoading"
|
|
>
|
|
确认设置
|
|
</ElButton>
|
|
</template>
|
|
</ElDialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, reactive, computed, onUnmounted, watch } from 'vue'
|
|
import { ElDialog, ElForm, ElFormItem, ElSelect, ElOption, ElButton } from 'element-plus'
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|
|
|
interface Props {
|
|
modelValue: boolean
|
|
confirmLoading?: boolean
|
|
}
|
|
|
|
type SpeedTierCode = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
|
|
|
|
interface Emits {
|
|
(e: 'update:modelValue', value: boolean): void
|
|
(e: 'confirm', data: { code: SpeedTierCode }): void
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
confirmLoading: false
|
|
})
|
|
const emit = defineEmits<Emits>()
|
|
|
|
const formRef = ref<FormInstance>()
|
|
const speedTiers = [
|
|
{ code: -1, label: '不限速' },
|
|
{ code: 0, label: '0kbps' },
|
|
{ code: 1, label: '128Kbps' },
|
|
{ code: 2, label: '512Kbps' },
|
|
{ code: 3, label: '1Mbps' },
|
|
{ code: 4, label: '2Mbps' },
|
|
{ code: 5, label: '10Mbps' },
|
|
{ code: 6, label: '20Mbps' },
|
|
{ code: 7, label: '50Mbps' },
|
|
{ code: 8, label: '100Mbps' }
|
|
] as const
|
|
|
|
const form = reactive<{ code: SpeedTierCode | undefined }>({ code: undefined })
|
|
|
|
const rules: FormRules = {
|
|
code: [{ required: true, message: '请选择限速档位', trigger: 'change' }]
|
|
}
|
|
|
|
const visible = computed({
|
|
get: () => props.modelValue,
|
|
set: (value) => emit('update:modelValue', value)
|
|
})
|
|
|
|
// 监听对话框打开,重置表单
|
|
const setLayoutScrollLock = (locked: boolean) => {
|
|
document
|
|
.querySelector<HTMLElement>('.layouts')
|
|
?.classList.toggle('speed-limit-scroll-locked', locked)
|
|
}
|
|
|
|
watch(
|
|
visible,
|
|
(newVal) => {
|
|
setLayoutScrollLock(newVal)
|
|
if (newVal) {
|
|
form.code = undefined
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
onUnmounted(() => {
|
|
setLayoutScrollLock(false)
|
|
})
|
|
|
|
const handleCancel = () => {
|
|
visible.value = false
|
|
}
|
|
|
|
const handleConfirm = async () => {
|
|
if (props.confirmLoading) return
|
|
if (!formRef.value) return
|
|
|
|
try {
|
|
await formRef.value.validate()
|
|
if (form.code === undefined) return
|
|
emit('confirm', {
|
|
code: form.code
|
|
})
|
|
} catch (error) {
|
|
console.error('表单验证失败:', error)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.speed-limit-modal .el-dialog__body {
|
|
overflow: visible;
|
|
}
|
|
|
|
.speed-limit-select-popper {
|
|
z-index: 4001 !important;
|
|
overscroll-behavior: contain;
|
|
}
|
|
|
|
.speed-limit-select-popper .el-select-dropdown__wrap,
|
|
.speed-limit-select-popper .el-scrollbar__wrap {
|
|
max-height: none !important;
|
|
overflow-y: visible !important;
|
|
}
|
|
|
|
.speed-limit-modal {
|
|
overflow: hidden;
|
|
overscroll-behavior: contain;
|
|
}
|
|
|
|
.layouts.speed-limit-scroll-locked {
|
|
overflow: hidden !important;
|
|
}
|
|
</style>
|