haoxuan
2023-11-03 26ffbb096df8f0dc7f851b1af23fea7136fcfaea
没有背景图的弹框封装+设备选择的弹框组件开发
2个文件已添加
2个文件已修改
227 ■■■■■ 已修改文件
src/components.d.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/CommonModal.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/DashboardTitle.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/components/DeviceCheckList.vue 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts
@@ -9,6 +9,8 @@
  export interface GlobalComponents {
    AlertLightIcon: typeof import('./components/icons/AlertLightIcon.vue')['default']
    BaseModal: typeof import('./components/BaseModal.vue')['default']
    CommonModal: typeof import('./components/CommonModal.vue')['default']
    copy: typeof import('./components/BaseModal copy.vue')['default']
    DashboardLayout: typeof import('./components/DashboardLayout.vue')['default']
    ElButton: typeof import('element-plus/es')['ElButton']
    ElCollapse: typeof import('element-plus/es')['ElCollapse']
src/components/CommonModal.vue
New file
@@ -0,0 +1,84 @@
<template>
  <div class="base-modal" :class="{ wider: props.wider }">
    <el-dialog v-model="modelData" :close-on-click-modal="false" width="753px" :show-close="false">
      <template #header>
        <div class="modal-title">
          <div class="modal-title-text">
            <slot name="title"></slot>
          </div>
          <div class="modal-title-close" @click="closeModal">
            <el-icon :size="22"><CloseBold /></el-icon>
          </div>
        </div>
      </template>
      <template #default>
        <slot name="default"></slot>
      </template>
      <template #footer>
        <slot name="footer"></slot>
      </template>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
import { CloseBold } from '@element-plus/icons-vue'
export interface BaseModalProps {
  /** 是否展示模态框 */
  modelValue: boolean
  /** 更宽版本 */
  wider: boolean
}
const props = withDefaults(defineProps<BaseModalProps>(), {
  modelValue: false,
  wider: false
})
const emit = defineEmits<{
  'update:modelValue': [show: boolean]
  close: []
}>()
const modelData = useVModel(props, 'modelValue', emit)
function closeModal() {
  emit('close')
}
</script>
<style scoped lang="scss">
$status-ready: #10256c;
$status-done: #0059ffd0;
:deep(.el-dialog) {
  width: 553px;
  min-height: 200px;
  height: auto;
  background: $status-ready;
}
.wider {
  :deep(.el-dialog) {
    width: 938px;
    height: 733px;
    background: $status-ready;
  }
}
.modal-title {
  position: relative;
  display: flex;
  align-items: center;
  &-text {
    padding-left: 12px;
    font-size: 20px;
    font-weight: 600;
  }
  &-close {
    cursor: pointer;
    position: absolute;
    display: flex;
    justify-content: center;
    align-items: center;
    top: 0px;
    right: 0px;
  }
}
</style>
src/views/dashboard/components/DashboardTitle.vue
@@ -23,7 +23,7 @@
      </div>
    </div>
  </div>
  <DeviceCheckList v-model="showDevicesModal" :devices="deviceList"></DeviceCheckList>
  <TroubleTrackerModal v-model="showProblemsModal" :problems="problemList"></TroubleTrackerModal>
</template>
<script setup lang="ts">
@@ -31,6 +31,7 @@
import { computed, onUnmounted, ref } from 'vue'
import { useDevicesStore } from '@/stores/devices'
import TroubleTrackerModal from '@/views/dashboard/components/TroubleTrackerModal.vue'
import DeviceCheckList from '@/views/dashboard/components/DeviceCheckList.vue'
import IconCloudDone from '~icons/material-symbols-light/cloud-done-outline'
import IconCloudOff from '~icons/material-symbols-light/cloud-off-outline'
import IconSlider from '~icons/bx/slider'
src/views/dashboard/components/DeviceCheckList.vue
New file
@@ -0,0 +1,138 @@
<template>
  <div class="device-check-list">
    <CommonModal v-model="modelData" @close="closeModal">
      <template #title>设备选择</template>
      <div class="device-box">
        <el-scrollbar always class="scroller">
          <template v-if="devices?.length">
            <div
              v-for="(item, index) in devices"
              :key="index"
              :class="item.checked ? 'device-item check-item' : 'device-item'"
              @click="deviceClick(index)"
            >
              <div class="item-l">
                <span>{{ item.number }}</span>
                {{ item.name }}
              </div>
              <div v-if="item.checked" class="item-r">
                <el-icon class="item-icon" size="22" color="#00ff00"><CircleCheckFilled /></el-icon>
              </div>
            </div>
          </template>
        </el-scrollbar>
      </div>
      <template #footer>
        <div class="device-b dialog-footer">
          <BigButton class="btn1" bg-color="#213e9e" @click="closeModal">取消</BigButton>
          <BigButton class="btn" bg-color="#0dfde6" @click="saveModal">保存</BigButton>
        </div>
      </template>
    </CommonModal>
  </div>
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
import { CircleCheckFilled } from '@element-plus/icons-vue'
import BigButton from '@/views/dashboard/components/BigButton.vue'
import { ref } from 'vue'
export interface DeviceCheckListProps {
  modelValue: boolean
}
const props = withDefaults(defineProps<DeviceCheckListProps>(), {
  modelValue: false
})
const emit = defineEmits<{
  'update:modelValue': [show: boolean]
}>()
const modelData = useVModel(props, 'modelValue', emit)
const devices = ref([
  {
    number: '111',
    name: '设备A',
    checked: true
  },
  {
    number: '222',
    name: '设备b'
  }
])
function closeModal() {
  modelData.value = false
}
function saveModal() {}
const deviceClick = (index) => {
  devices.value.find((ele) => (ele.checked = false))
  devices.value[index].checked = true
}
</script>
<style scoped lang="scss">
$status-done: #0dfde6;
$status-d: #213e9e;
:deep(.el-dialog__body) {
  padding-top: 10px !important;
  padding-bottom: 10px !important;
}
.device-box {
  height: 200px;
  overflow-y: auto;
  .check-item {
    border: 1px solid $status-done;
  }
  .device-item {
    box-sizing: border-box;
    width: 100%;
    height: 45px;
    line-height: 45px;
    padding: 0 10px;
    border-radius: 6px;
    font-size: 14px;
    color: #fff;
    cursor: pointer;
    .item-l {
      width: calc(100% - 80px);
      float: left;
      span {
        margin-right: 10px;
      }
    }
    .item-icon {
      height: 100%;
      display: flex;
      align-items: center;
    }
    .item-r {
      height: 100%;
      float: right;
    }
  }
}
.device-b {
  width: 210px;
  margin: 10px auto 10px;
  display: flex;
  align-items: center;
  .btn,
  .btn1 {
    width: 100px;
    height: 40px;
    line-height: 40px;
    border-radius: 4px;
    float: left;
    color: #333;
    font-size: 14px;
    cursor: pointer;
    text-align: center;
  }
  .btn1 {
    color: #fff;
    margin-right: 10px;
  }
}
.scroller {
  padding: 4px 16px;
}
</style>