前言
因为之前只是用Vue来开发IaaS平台项目,其使用场景通常都是PC,所以没怎么涉及到Web响应式设计开发相关知识。最近项目刚好是应用在PC和平板,甚至是手机上的,所以就需要考虑响应式的问题。
1. 技术选型
Web响应式开发,主要是基于CSS里@media媒体查询实现,允许不同视图尺寸使用不同的布局。
1.1 方案一:Vue 3 + Vite + Bootstrap5
1.1.1 优点
容易上手:只要对 HTML 和 CSS 有基本了解的人都可以很快速的使用 Bootstrap。
响应式设计:Bootstrap 可以根据不同平台(手机、平板电脑和台式机)进行调整。
移动优先:在 Bootstrap 中,自适应移动端是框架的核心部分。
浏览器兼容性:Bootstrap5 兼容所有主流浏览器(Chrome、Firefox、Edge、Safari 和 Opera)。 如果您需要支持 IE11 及以下版本,请使用 Bootstrap4 或 Bootstrap3。
github 星数 164k
Bootstrap5 效果演示:https://www.bootstrap-admin.top/
1.1.2 缺点
没办法使用我们积累的vue next组件库
Bootstrap5 需要学习成本,但不会很难
相对紧急的项目,通常不应该引入新技术去开发实现,而是以快速交付为主。
1.2 方案二:Vue 3 + Vite + Element Plus + @media
1.2.1 优点
- 基于前端现有技术积累,可快速开发项目功能
1.2.2 缺点
前端封装组件库,并没考虑过响应式设计,潜在未知样式问题,如开发此项目,各组件需考虑各平台(电脑、平板、手机)屏幕适配的同时,还要考虑已引用该库开发的项目兼容性问题。
@media媒体查询需每个页面、每个平台去适配(Bootstrap5做的事情),工作量相对较大,因无更多平台设备去验证,潜在未知的样式问题。
1.3 结论
简单来说,可以理解为方案一Bootstrap5帮我们处理好了屏幕适配的问题,我们只需要关注功能开发即可,方案二则是功能也要开发,样式也要关注。长远来看,倾向于方案一开发。
2. 快速搭建
Bootstrap5官方文档有提供Vite基于开发的指南《Bootstrap & Vite》,我们虽然是基于Vue3开发的,但是相关配置基本都一样的,只是有一点点差异而已。
2.1 下载
通过Vite直接生成基于Typescript开发的Vue3模版。
npm create vite@latest my-vue-app -- --template vue-ts
2.2 安装
npm install
// bootstrap5、popperjs
npm install --save bootstrap @popperjs/core
// sass
npm install --save-dev sass
// bootstrap-icons 官方图标库
npm install bootstrap-icons
2.3 配置
2.3.1 开发热重载
在vite.config.ts
中配置,我们需要让Vite知道在哪里可以找到我们项目的TypeScript,以及开发服务器应该如何表现(热重载从src文件夹中拉取)。
import path from 'path'
export default defineConfig({
resolve: {
alias: {
root: path.resolve(__dirname, 'src'),
}
},
server: {
port: 8080,
host: true
}
})
2.3.2 Bootstrap5
在
vite.config.ts
中配置,让导入变得尽可能简单:resolve: { alias: { '~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'), } }
在
src/assets/style
文件夹新建一个文件bootstrap5.scss
,引入bootstrap5样式:@import "~bootstrap/scss/bootstrap";
将
main.ts
文件修改为main.js
,然后在index.html
中同步修改:<script type="module" src="/src/main.js"></script>
在
main.js
中引入bootstrap5
:// 自定义样式 import '../src/assets/style/bootstrap5.scss' // Bootstrap5 JS import * as bootstrap from 'bootstrap'
2.3 验证
<div class="container mt-3">
<h2 class="my-3 text-start">按钮样式</h2>
<button type="button" class="btn">基本按钮</button>
<button type="button" class="btn btn-primary ms-2">主要按钮</button>
<button type="button" class="btn btn-secondary ms-2">次要按钮</button>
<button type="button" class="btn btn-success ms-2">成功</button>
<button type="button" class="btn btn-info ms-2">信息</button>
<button type="button" class="btn btn-warning ms-2">警告</button>
<button type="button" class="btn btn-danger ms-2">危险</button>
<button type="button" class="btn btn-dark ms-2">黑色</button>
<button type="button" class="btn btn-light ms-2">浅色</button>
<button type="button" class="btn btn-link ms-2">链接</button>
</div>
2.4 效果
3. 组件
3.1 日期选择器
一开始打算使用<input type="datetime-local">
实现的,但是效果不是很理想,一些样式调整起来很复杂,加上本着不重复造轮子的思想,就打算引用相关日期插件实现。
- 安装
npm install @popperjs/core @eonasdan/tempus-dominus
- main.js中引入样式
// 日期组件样式
import '@eonasdan/tempus-dominus/dist/css/tempus-dominus.css'
- 在.vue中使用时,需引入
import { TempusDominus} from '@eonasdan/tempus-dominus';
import { name } from "@eonasdan/tempus-dominus/dist/locales/ru";
- 实现代码
<div class="input-group mb-3" id="datetimepicker1">
<input type="text" class="form-control" readonly aria-label="">
<span class="input-group-text"><i class="bi bi-calendar"></i></span>
</div>
onMounted(() => {
const element: any = document.getElementById('datetimepicker1')
var datetimepicker1 = new TempusDominus(element, {
localization: {
format: 'yyyy-MM-dd HH:mm:ss',
hourCycle: 'h24'
},
display: {
viewMode: 'calendar',
components: {
year: true,
month: true,
date: true,
clock: true,
hours: true,
minutes: true,
seconds: true
},
icons: {
time: 'bi bi-clock',
date: 'bi bi-calendar',
up: 'bi bi-arrow-up',
down: 'bi bi-arrow-down',
previous: 'bi bi-chevron-left',
next: 'bi bi-chevron-right',
today: 'bi bi-calendar-check',
clear: 'bi bi-trash',
close: 'bi bi-x',
},
buttons: {
today: true,
clear: true,
close: true,
},
}
});
datetimepicker1.locale(name);
})
- 效果如下
3.2 自定义主题色
因为Bootstrap5主题默认是蓝色,和项目设计的主题色不一致,所以就需要修改定制主题色,这一块在官网Sass模块也有详细说明。特别注意的是,同一Sass文件中的变量覆盖可以在默认变量之前或之后。但是,当跨Sass文件覆盖时,必须在导入Bootstrap的Sass文件之前进行覆盖。比如要将主题色修改为紫色(#6610f2),就需要在我们自定义的样式文件bootstrap5.scss中设置,如下所示:
$primary: #6610f2;
$danger: #ff4136;
$theme-colors: (
"primary": $primary,
"danger": $danger
);
// scss
@import "~bootstrap/scss/bootstrap";
// Required
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/mixins";
效果如下图所示,可以看到按钮设置为primary
时,颜色已经变成紫色(#6610f2)了,但是出现了一个问题,那就是次要按钮、成功、信息等按钮样式异常。
为了解决这个问题,就去查看下_variables.scss
文件,其中有一段样式代码:
// scss-docs-start theme-color-variables
$primary: $blue !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-900 !default;
也就是我们在自定义样式中覆盖了,导致相关字段颜色值丢失,所以就在自定义样式文件中,补上,如下所示:
// 修改主题色
$primary: #6610f2;
$secondary: #6c757d;
$success: #198754;
$info: #0dcaf0;
$warning: #ffc107;
$danger: #dc3545;
$light: #f8f9fa;
$dark: #212529;
$theme-colors: (
"primary": $primary,
"secondary": $secondary,
"success": $success,
"info": $info,
"warning": $warning,
"danger": $danger,
"light": $light,
"dark": $dark,
);
效果如下所示,虽然解决了按钮的样式问题,但是其他组件其实可能有潜在的问题,这一块后续再补充。
3.3 Echarts
3.3.1 安装
npm install echarts --save
3.3.2 引入 ECharts
因为Echarts官网上面其实都有Demo的,但是结合我们实际项目,还是可以把相对贴切的模版给出来的,如下所示:
<template>
<div class="card">
<div id="echarts" style="width: 500px; height: 300px;"></div>
</div>
</template>
<script setup lang="ts">
import * as echarts from 'echarts';
import { onMounted } from 'vue';
onMounted(() => {
// 基于准备好的dom,初始化echarts实例
const element: any = document.getElementById('echarts')
const myChart: any = echarts.init(element);
const colors = ['#5470C6', '#91CC75', '#EE6666'];
const options = {
color: colors,
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
grid: {
left: '30%'
},
legend: {
data: ['电压', '电流', '功率']
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
},
// prettier-ignore
data: ['06:00:00', '07:00:00', '08:00:00', '09:00:00', '10:00:00', '12:00:00', '14:10:00', '15:30:00', '16:00:00', '17:00:00', '18:00:00', '19:00:00']
}
],
yAxis: [
{
type: 'value',
name: '电压',
position: 'left',
alignTicks: true,
offset: 0,
axisLine: {
show: true,
lineStyle: {
color: colors[0]
}
},
axisLabel: {
formatter: '{value} V'
}
},
{
type: 'value',
name: '电流',
position: 'left',
alignTicks: true,
offset: 50,
axisLine: {
show: true,
lineStyle: {
color: colors[1]
}
},
axisLabel: {
formatter: '{value} A'
}
},
{
type: 'value',
name: '功率',
position: 'left',
alignTicks: true,
offset: 100,
axisLine: {
show: true,
lineStyle: {
color: colors[2]
}
},
axisLabel: {
formatter: '{value} KW'
}
}
],
series: [
{
name: '电压',
type: 'line',
data: [
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
]
},
{
name: '电流',
type: 'line',
yAxisIndex: 1,
data: [
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
]
},
{
name: '功率',
type: 'line',
yAxisIndex: 2,
data: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
}
]
};
// 绘制图表
myChart.setOption(options);
})
</script>
<style scoped>
</style>
3.3.2 屏幕自适应
因为使用Bootstrap5开发本身就是为了Web响应式功能,所以Echarts也需要处理屏幕自适应的问题,这个ECharts官方文档已经有相关说明了《响应容器大小的变化》,如下所示:
<style>
#main,
html,
body {
width: 100%;
}
#main {
height: 400px;
}
</style>
<div id="main"></div>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
window.addEventListener('resize', function() {
myChart.resize();
});
</script>
3.3.3 热更新
待解决。
4. 打包
4.1 本地打开
因为项目应用场景不太一样,所以有些时候是想要直接打开dist/index.html
就可以看到网页内容的,实现这个有现成的插件可以使用vite-plugin-singlefile,其原理就是将js
和css
文件内容填充到index.html
里,这样就可以通过打开index.html
查看打包好的项目了。如下所示:
- 安装
npm install vite-plugin-singlefile --save-dev
- 在vite.config.ts中配置
import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import { viteSingleFile } from "vite-plugin-singlefile"
export default defineConfig({
plugins: [vue(), viteSingleFile()],
})