three.js中对vue3的数字孪生使用模板布局
一.安装 Vue-router
pnpm add vue-router@4
-- main.ts
/* 路由表 */
import router from "../src/router/index";
app.use(router)
1. 创建router.js
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'three',
component: () => import('../components/three/three.vue'),
children:[
{
path: '/',
name: 'three',
component: () => import('../components/three/three.vue'),
},
{
path: '/three2',
name: 'three2',
component: () => import('../components/three/three2.vue'),
},
]
},
]
const router = createRouter({
history: createWebHashHistory(),
routes,
});
export default router
二. App.vue布局
<script setup lang="ts">
import { ref,onMounted, } from 'vue';
let web3d = ref<HTMLElement>()
onMounted(() => {
/* 须在dom节点后 渲染 */
web3d.value?.appendChild(renderer.domElement);
document.getElementById('web3d')?.appendChild(renderer.domElement);
})
</script>
<template>
<div id="app">
<div id="ech">
<router-view>/* 可视化图表 */</router-view>
</div>
/* three.场景 */
<div class="three">
<div id="web3d" ref='web3d'> </div>
</div>
<div id="footerNav">
<div class="footer-body">
<el-menu :ellipsis="false" class="el-menu-popper-demo" mode="horizontal" :popper-offset="10" :router="true" style="max-width: 600px">
<el-menu-item index="/">社区首页</el-menu-item>
<el-sub-menu index="2">
<template #title>智慧管理</template>
<el-menu-item @click="webbolFn" index="/three2">智慧小咪</el-menu-item>
<el-menu-item index="/three3">智慧大汪</el-menu-item>
</el-sub-menu>
</el-menu>
</div>
</div>
</div>
</template>
<style scoped>
#ech {
position: absolute;z-index: 3;pointer-events: none;
}
#web3d {
display: flex;
justify-content: center;
}
#footerNav {
height: 60px;
background-color: #cccccc;
position: absolute;
bottom: 20px;
left: 50%;
right: 50%;
/* z-index: 2; */
/* transform: translate(-50%, 0); */
display: flex;
justify-content: center;
}
</style>
<style>
.el-menu--popup {
min-width: 137px !important;
}
</style>
1.ech图表组件
<script setup lang='ts'>
import { ref, onMounted } from 'vue';
let show = ref(false)
onMounted(() => {
show.value = true;
})
</script>
<template>
<div id='three'>
<div class="three-body">
<Transition name="fade1">
<div v-if="show && store.webthreebol">
<div>
<div class="echarts">
<echartsLeft1></echartsLeft1>
</div>
</div>
</div>
</Transition>
<Transition name="fade2">
<div v-if="show" style="display: flex;">
<div class="echarts">
<echartsRig1></echartsRig1>
</div>
</div>
</Transition>
</div>
</div>
</template>
<style>
#three {
max-width: 100vw;
height: 100%;
box-sizing: border-box;
padding: 30px 20px;
}
.three-body{
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
border: 1px solid #919191;
}
/* 进入和离开动画可以使用不同 持续时间和速度曲线。*/
/* 进入动画 */
.fade1-enter-active {
transition: all 1s ease-out;
}
/* 离开动画 */
.fade1-leave-active {
transition: all 1s cubic-bezier(1, 0.5, 0.8, 0);
}
/* 进入始状态 */
.fade1-enter-from,
/* 进入末状态 */
.fade1-leave-to {
transform: translateX(-40px);
opacity: 0;
}
</style>
2.echarts-1文件夹
echarts1-left.vue
<script setup lang='ts'>
import { ref, onMounted, } from 'vue';
import * as echarts from 'echarts';
const echlefTet1 = ref(null);
onMounted(() => {
const myChart = echarts.init(echlefTet1.value);
let option = {};
option && myChart.setOption(option);
});
</script>
<template>
<div id='echarts1-left'>
<div ref="echlefTet1" class="echlefTet1"></div>
</div>
</template>
<style scoped>
.echlefTet1 {
box-sizing: border-box;
width: 400px; height: 200px;
pointer-events: auto;
padding: 5px;
}
</style>