项目环境搭建
使用create-vue初始化项目
npm init vue@latest
准备utils模块
业务背景:大屏项目属于后台项目的一个子项目,用户的token是共享的
后台项目 - token - cookie
大屏项目要以同样的方式把token获取到,然后拼接到axios的请求头中
1. 封装cookies存取模块
npm i js-cookie
utils/cookie.js
import Cookies from 'js-cookie'
const KEY = 'token_key'
export function getCookie () {
return Cookies.get(KEY)
}
export function setCookie (value) {
Cookies.set(KEY, value)
}
export function removeCookie () {
Cookies.remove(KEY)
}
2. 封装request请求模块
npm i axios
utils/request.js
import axios from 'axios'
import { getCookie } from './cookie'
const service = axios.create({
baseURL: 'https://api-hmzs.itheima.net/v1',
timeout: 5000 // request timeout
})
// 请求拦截器
service.interceptors.request.use(
config => {
const token = getCookie()
if (token) {
config.headers.Authorization = token
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
return response.data
},
error => {
return Promise.reject(error)
}
)
export default service
路由搭建
1- 创建路由组件
<script setup>
</script>
<template>
<div>我是大屏显示组件</div>
</template>
2- 绑定路由
// createRouter: 创建路由实例对象
// createWebHistory: 创建history模式的路由(hash / history)
import { createRouter, createWebHistory } from 'vue-router'
// 导入路由级别的组件
import HomeView from '../views/HomeView.vue'
import BigScreenView from '../views/BigScreenView.vue'
const router = createRouter({
// 类似于mode:history 指定路由为history模式
history: createWebHistory(import.meta.env.BASE_URL),
// 配置路由path和component对应关系
routes: [
{
path: '/',
redirect: '/big-screen',
name: 'home',
component: HomeView,
},
{
path: '/big-screen',
name: 'big-screen',
component: BigScreenView
}
]
})
export default router
初始化样式
1.备初始化文件
styles/common.scss
html,
body,
#app {
height: 100vh;
overflow: hidden;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
2. 安装sass
create-vue创建的项目默认不支持scss语法,需要我们手动安装sass
npm i sass
2D可视化
cookie共享问题
- 前提 cookie / ls / session 本身会有跨域问题 不同域下的cookie信息是不共享的
- 在主域名一致的情况下,可以让cookie信息实现共享
- 把后台项目启动起来登录一下,把token存入本地
1. 准备静态模版
2. 封装接口并请求数据
3. 渲染图表
1- 安装echarts
npm install echarts
2- 封装初始化方法并在mounted中执行
三步走()
import * as echarts from 'echarts'
// 渲染年度收入分析图表
const initBarChart = () => {
// 1. 解构图表数据
const { parkIncome } = parkInfo.value
// 2. 准备options数据
const barOptions = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
grid: {
// 让图表占满容器
top: '10px',
left: '0px',
right: '0px',
bottom: '0px',
containLabel: true,
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true,
show: false,
},
data: parkIncome.xMonth,
},
],
yAxis: [
{
type: 'value',
splitLine: {
show: false,
},
},
],
series: [
{
name: '园区年度收入',
type: 'bar',
barWidth: '10px',
data: parkIncome.yIncome.map((item, index) => {
const color =
index % 2 === 0
? new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0.23, color: '#74c0f8' },
{ offset: 1, color: 'rgba(116,192,248,0.00)' },
])
: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0.23, color: '#ff7152' },
{ offset: 1, color: 'rgba(255,113,82,0.00)' },
])
return { value: item, itemStyle: { color } }
}),
},
],
textStyle: {
color: '#B4C0CC',
},
}
// 3. 渲染图表
const myBarChart = echarts.init(barChart.value)
myBarChart.setOption(barOptions)
}
拆分优化对比
-
基于组件拆分
-
- 解决什么问题:复用 + 增加可维护性
- 拆分的是什么:.vue = HTML + JS + CSS
- 带来问题:一旦组件从一个变成了多个 必定形成嵌套关系 增加通信成本
-
基于逻辑拆分
-
- 解决什么问题:复用(逻辑) + 增加可维护性
- 拆分的是什么: 拆分的只有js
- 带来的问题:对原生js函数的理解要求高了
-
基于逻辑的通用拆分思想
-
- 找到组件中属于同一个业务逻辑的所有代码(响应式数据 + 修改数据的方法)
- 定义一个以
use
打头的方法,把第一步所有的业务逻辑代码都放入 - 在use函数内部,把组件中要用到的数据或者方法以对象的方式导出
- 在组件的setup语法糖中,通过调用函数配合解构赋值把函数内部的数据和方法在组件中可用
3D可视化
3D可视化的搭建流程说明
前端加载3D模型
需求:在浏览器中渲染出来3D模型
1. 下载模型解析包
说明:模型解析包和制作3D的软件是配套的
npm i @splinetool/runtime
2. 拉取模型并渲染
说明:spline实例既可以拉取模型同时拉取完毕之后会在canvas节点上渲染画布
<script setup>
// 导入模型解析构造函数
import { Application } from '@splinetool/runtime'
import { onMounted, ref } from 'vue'
// 初始化3d模型
const ref3d = ref(null)
const publicPath = 'https://fe-hmzs.itheima.net'
const init3dModel = () => {
// 实例化解析器实例
let spline = new Application(ref3d.value)
// 拉取模型
spline.load(`${publicPath}/scene.splinecode`).then(() => {
console.log('3D模型加载并渲染完毕')
})
}
// dom节点渲染完毕再加载
onMounted(() => {
init3dModel()
})
</script>
<template>
<div class="model-container">
<!-- 准备3D渲染节点 -->
<canvas class="canvas-3d" ref="ref3d" />
</div>
</template>
<style scoped lang="scss">
.model-container {
height: 100%;
background-color: black;
width: 100%;
flex-shrink: 0;
}
</style>
3. 添加进入条
纯展示类组件,只需要设计一个参数,显示隐藏
loading prop true 显示 false 隐藏
1- 封装组件
LoadingComponent.vue
<script setup>
defineProps({
loading: {
type: Boolean,
default: false
}
})
</script>
<template>
<div v-if="loading" class="loading">
<p class="text">园区资源加载中…</p>
<div class="loading-process">
<div class="process-wrapper"></div>
</div>
</div>
</template>
<style lang="scss">
.loading {
position: absolute;
left: 66%;
top: 40%;
transform: translateX(-50%);
text-align: center;
.text {
font-size: 14px;
color: #909399;
margin-bottom: 16px;
}
.loading-process {
width: 280px;
height: 4px;
background: rgba(255, 255, 255, 0.16);
border-radius: 20px;
overflow: hidden;
}
.process-wrapper {
height: 100%;
width: 5%;
background: linear-gradient(90deg, #48ffff 0%, #3656ff 100%);
animation-duration: 1000s;
animation-name: loading;
}
@keyframes loading {
0% {
transform: scaleX(1);
}
1% {
transform: scaleX(38);
}
100% {
transform: scaleX(40);
}
}
}
</style>
2- 导入loading根据状态控制显示
<script setup>
import { onMounted, ref } from 'vue'
// 导入模型解析构造函数
import { Application } from '@splinetool/runtime'
// 导入loading组件
import LoadingComponent from '@/components/LoadingComponent.vue'
// 调用接口拉取3d模型 渲染视图中
const publisPath = 'https://fe-hmzs.itheima.net'
const ref3d = ref(null)
const showLoading = ref(false)
const init3dModel = () => {
// 开启loading
showLoading.value = true
// 1. 实例解析器对象(传入模型将来渲染的节点对象)
const spline = new Application(ref3d.value)
// 2. 使用对象load方法去拉取3大模型资源
spline.load(`${publisPath}/scene.splinecode`).then(() => {
showLoading.value = false
// 模型渲染完毕之后后续的逻辑操作
// 3. 拉取资源之后.then方法中可以做后续的逻辑操作
})
}
onMounted(async () => {
// 获取原生的dom对象
// 这个方法执行的时候 虽然在mounted中执行的 但是不能保证依赖的数据已经通过接口返回了
// 解决方案:等到数据返回之后才进行初始化操作
await getParkInfo()
initBarChart()
initPieChart()
init3dModel()
})
</script>
<template>
<!-- 3d模型渲染节点 -->
<div class="model-container">
<!-- 进度条 -->
<LoadingComponent :loading="showLoading" />
<!-- 准备3D渲染节点 -->
<canvas class="canvas-3d" ref="ref3d" />
</div>
</template>
大屏适配
适配方案说明
缩放方案:接入难度非常小 效果中上
GitHub - Alfred-Skyblue/v-scale-screen: Vue large screen adaptive component vue大屏自适应组件
使用组件
1.安装组件
npm i v-scale-screen
2. 使用组件并制定宽高
注:以 1920 * 1080 为标准尺寸比
<v-scale-screen width="1920" height="1080">
主体内容盒子
</v-scale-screen>
=“showLoading” />
大屏适配
适配方案说明
缩放方案:接入难度非常小 效果中上
GitHub - Alfred-Skyblue/v-scale-screen: Vue large screen adaptive component vue大屏自适应组件
使用组件
1.安装组件
npm i v-scale-screen
2. 使用组件并制定宽高
注:以 1920 * 1080 为标准尺寸比
<v-scale-screen width="1920" height="1080">
主体内容盒子
</v-scale-screen>