前端项目采用响式布局

要让整个前端项目采用响应式布局,可以从多个方面进行优化,以下是一些具体的建议和实现方法:

1. 使用 ElementPlus 的响应式特性

ElementPlus 组件库本身提供了一些响应式的能力,例如 el-col 组件可以用于创建响应式的网格布局。你可以在需要的地方使用这些组件来实现响应式效果。

2. 使用媒体查询

媒体查询是实现响应式布局的常用方法,可以根据不同的屏幕尺寸应用不同的样式。

修改 src/style.css
:root {
  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  font-weight: 500;
  color: #646cff;
  text-decoration: inherit;
}
a:hover {
  color: #535bf2;
}

body {
  margin: 0;
  display: flex;
  place-items: center;
  min-width: 320px;
  min-height: 100vh;
}

h1 {
  font-size: 3.2em;
  line-height: 1.1;
}

button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}
button:hover {
  border-color: #646cff;
}
button:focus,
button:focus-visible {
  outline: 4px auto -webkit-focus-ring-color;
}

.card {
  padding: 2em;
}

#app {
  max-width: 1280px;
  margin: 0 auto;
  padding: 2rem;
  text-align: center;
}

@media (prefers-color-scheme: light) {
  :root {
    color: #213547;
    background-color: #ffffff;
  }
  a:hover {
    color: #747bff;
  }
  button {
    background-color: #f9f9f9;
  }
}

/* 小屏幕设备(手机,小于 768px) */
@media (max-width: 767px) {
  #app {
    padding: 1rem;
  }
  /* 调整侧边栏宽度 */
  el-aside {
    width: 100% !important;
  }
}

/* 中等屏幕设备(平板,768px 到 991px) */
@media (min-width: 768px) and (max-width: 991px) {
  #app {
    max-width: 750px;
  }
}

/* 大屏幕设备(桌面,992px 到 1199px) */
@media (min-width: 992px) and (max-width: 1199px) {
  #app {
    max-width: 970px;
  }
}

/* 超大屏幕设备(大桌面,1200px 及以上) */
@media (min-width: 1200px) {
  #app {
    max-width: 1170px;
  }
}

3. 修改 src/components/Layout.vue

<template>
  <div>
    <el-header>
      <h1>Application Header</h1>
      <div style="float: right;">
        <span v-if="userInfo">{{ userInfo.username }}</span>
        <el-button @click="logout">Logout</el-button>
      </div>
    </el-header>
    <el-container>
      <el-aside :width="isMobile ? '100%' : '200px'">
        <el-menu :default-active="$route.name" mode="vertical">
          <el-menu-item index="Home">
            <template #title>
              <el-icon><HomeFilled /></el-icon>
              <span>Home</span>
            </template>
            <!-- 使用路由名称进行跳转 -->
            <router-link :to="{ name: 'Home' }"></router-link>
          </el-menu-item>
          <el-menu-item index="Devices">
            <template #title>
              <el-icon><Setting /></el-icon>
              <span>Devices</span>
            </template>
            <!-- 使用路由名称进行跳转 -->
            <router-link :to="{ name: 'Devices' }"></router-link>
          </el-menu-item>
          <el-menu-item index="Alarms">
            <template #title>
              <el-icon><Bell /></el-icon>
              <span>Alarms</span>
            </template>
            <!-- 使用路由名称进行跳转 -->
            <router-link :to="{ name: 'Alarms' }"></router-link>
          </el-menu-item>
          <el-menu-item index="Statistics">
            <template #title>
              <el-icon><DataAnalysis /></el-icon>
              <span>Statistics</span>
            </template>
            <!-- 使用路由名称进行跳转 -->
            <router-link :to="{ name: 'Statistics' }"></router-link>
          </el-menu-item>
        </el-menu>
      </el-aside>
      <el-main>
        <router-view></router-view>
      </el-main>
    </el-container>
    <el-footer>
      <p>Application Footer</p>
    </el-footer>
  </div>
</template>

<script>
import { HomeFilled, Setting, Bell, DataAnalysis } from '@element-plus/icons-vue';
import { useUserStore } from '@store';
import { useRouter } from 'vue-router';
import { ref, onMounted, watch } from 'vue';

export default {
  name: "Layout",
  components: {
    HomeFilled,
    Setting,
    Bell,
    DataAnalysis
  },
  setup() {
    const userStore = useUserStore();
    const router = useRouter();
    const userInfo = userStore.userInfo;
    const isMobile = ref(window.innerWidth < 768);

    const logout = () => {
      userStore.logout();
      router.push({ name: 'Login' });
    };

    const handleResize = () => {
      isMobile.value = window.innerWidth < 768;
    };

    onMounted(() => {
      window.addEventListener('resize', handleResize);
    });

    return {
      userInfo,
      logout,
      isMobile
    };
  }
};
</script>

<style scoped>
el-header {
  background-color: #333;
  color: white;
  text-align: center;
  line-height: 60px;
}

el-aside {
  background-color: #f4f4f4;
}

el-main {
  background-color: #e9eef3;
}

el-footer {
  background-color: #333;
  color: white;
  text-align: center;
  line-height: 60px;
}
</style>

4. 优化表格布局

对于表格组件(如 el-table),可以根据屏幕尺寸调整列的显示。

修改 src/views/device/DeviceListView.vue
<template>
  <div>
    <h1>Device List</h1>
    <!-- 添加添加按钮 -->
    <el-button type="primary" @click="goToAddDevice">Add Device</el-button>
    <el-table :data="devices" stripe>
      <el-table-column prop="id" label="ID" :show-overflow-tooltip="true"></el-table-column>
      <el-table-column prop="name" label="Name" :show-overflow-tooltip="true"></el-table-column>
      <el-table-column label="Actions" v-if="!isMobile">
        <template #default="scope">
          <el-button type="primary" @click="goToDeviceDetail(scope.row.id)">View Details</el-button>
          <el-button type="warning" @click="goToEditDevice(scope.row.id)">Edit</el-button>
          <el-button type="danger" @click="deleteDevice(scope.row.id)">Delete</el-button>
        </template>
      </el-table-column>
      <el-table-column label="Actions" v-if="isMobile">
        <template #default="scope">
          <el-button type="primary" @click="goToDeviceDetail(scope.row.id)">Details</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 显示错误信息 -->
    <div v-if="errorMessage">{{ errorMessage }}</div>
  </div>
</template>

<script>
import { getDevices, deleteDevice } from '@/services/deviceService';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { ref, onMounted, watch } from 'vue';

export default {
  name: "DeviceListView",
  data() {
    return {
      devices: [],
      errorMessage: ''
    }
  },
  setup() {
    const isMobile = ref(window.innerWidth < 768);

    const handleResize = () => {
      isMobile.value = window.innerWidth < 768;
    };

    onMounted(() => {
      window.addEventListener('resize', handleResize);
    });

    return {
      isMobile
    };
  },
  async created() {
    console.log('DeviceListView created'); // 添加日志
    try {
      const response = await getDevices();
      // 根据实际响应结构调整代码
      if (response && Array.isArray(response)) {
        this.devices = response;
      } else if (response && response.results) {
        this.devices = response.results;
      } else {
        this.devices = [];
        this.errorMessage = 'Unexpected response structure when fetching devices.';
        console.error(this.errorMessage);
      }
    } catch (error) {
      // 记录详细的错误信息
      this.errorMessage = `Error fetching devices: ${error.message}`;
      console.error(this.errorMessage);
    }
  },
  methods: {
    goToDeviceDetail(id) {
      this.$router.push({ name: 'DeviceDetail', params: { id } });
    },
    goToEditDevice(id) {
      this.$router.push({ name: 'DeviceEdit', params: { id } });
    },
    async deleteDevice(id) {
      try {
        await deleteDevice(id);
        ElMessage.success('Device deleted successfully');
        // 重新获取设备列表
        const response = await getDevices();
        if (response && Array.isArray(response)) {
          this.devices = response;
        } else if (response && response.results) {
          this.devices = response.results;
        } else {
          this.devices = [];
          this.errorMessage = 'Unexpected response structure when fetching devices.';
          console.error(this.errorMessage);
        }
      } catch (error) {
        ElMessage.error('Error deleting device');
        console.error('Error deleting device:', error);
      }
    },
    // 跳转到添加设备页面
    goToAddDevice() {
      this.$router.push({ name: 'DeviceAdd' });
    }
  }
}
</script>

<style scoped>
h1 {
  color: #333;
}
</style>

通过以上步骤,你可以让整个前端项目实现响应式布局,在不同的屏幕尺寸下都能有良好的显示效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小赖同学啊

感谢上帝的投喂

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值