修复tab切换多于动画效果和地图样式

main
zjlnb666 6 days ago
parent e27476bcc4
commit 9c34fe5e08

@ -2,12 +2,45 @@
import HeaderNav from "@/components/HeaderNav.vue";
import Footer from "@/components/Footer.vue"
import {nextTick, ref, watch} from 'vue';
import { useRoute, useRouter, RouterView } from 'vue-router';
const route = useRoute();
const router = useRouter();
const routerUpdateKey = ref(Date.now());
watch(
() => route.fullPath,
() => {
routerUpdateKey.value = Date.now(); // key
// DOM
nextTick(() => {
restoreMenuInteraction();
});
},
{ immediate: true, deep: true }
);
const restoreMenuInteraction = () => {
const menuItems = document.querySelectorAll('.menu-item'); //
menuItems.forEach(item => {
//
item.style.pointerEvents = 'auto';
item.removeAttribute('disabled');
//
item.onclick = null; //
item.addEventListener('click', (e) => {
//
const path = item.dataset.path; // data-path
if (path) {
router.push({ path });
}
});
});
};
</script>
<template>
<HeaderNav></HeaderNav>
<router-view></router-view>
<router-view :key="`${$route.fullPath}-${routerUpdateKey}`"></router-view>
<Footer></Footer>
</template>

@ -15,3 +15,4 @@ button{
.hover-effect{
cursor: pointer;
}

@ -1,8 +1,9 @@
<script setup>
import {onBeforeMount, onBeforeUnmount, onMounted, ref} from 'vue'
import {nextTick, onBeforeMount, onBeforeUnmount, onMounted, ref} from 'vue'
import { Search } from '@element-plus/icons-vue'
import router from "@/router/index.js";
import {useRoute} from "vue-router";
import Mask from "@/components/Mask.vue";
const activeMenuIndex=ref(localStorage.getItem('activeMenu') || null)
const menuKey = ref(0)
@ -40,11 +41,20 @@ const goHome=()=>{
router.push('/')
}
const goWebsite=()=>{
console.log('返回官网')
window.location.href='http://www.philisense.com/index.html'
}
//
const visible=ref(false)
const searchInputRef=ref(null)
const input1 = ref('')
const openSearchMask=()=>{
visible.value=true
nextTick(()=>{
searchInputRef.value.focus()
})
}
</script>
<template>
@ -71,12 +81,12 @@ const input1 = ref('')
<el-menu-item index="/product">解决方案</el-menu-item>
<el-menu-item index="/service">服务交流</el-menu-item>
<el-menu-item index="/about">关于我们</el-menu-item>
<el-menu-item @click="goWebsite" index="/">返回官网</el-menu-item>
</el-menu>
<div @click="goWebsite" class="returnWebsite">
返回官网
</div>
<div>
<el-input
v-model="input1"
:style="{
'--el-input-border-radius': '35px',
'--el-input-bg-color': '#FFFFFF57',
@ -89,6 +99,7 @@ const input1 = ref('')
size="large"
placeholder="关键词搜索"
:suffix-icon="Search"
@focus="openSearchMask()"
/>
</div>
<div>
@ -98,7 +109,16 @@ const input1 = ref('')
</div>
</div>
</div>
<Mask :visible="visible" @close="visible=false" content-style="padding: 0">
<el-input
ref="searchInputRef"
v-model="input1"
:suffix-icon="Search"
placeholder="关键词搜索产品、文档、新闻"
size="large"
style="height:52px; font-size: 20px; width: 573px;"
></el-input>
</Mask>
</template>
<style scoped lang="less">
@ -182,8 +202,10 @@ const input1 = ref('')
}
.returnWebsite{
padding: 0 20px;
cursor: pointer;
}
</style>

@ -0,0 +1,88 @@
<script setup>
const props = defineProps({
//
visible: {
type: Boolean,
default: false
},
//
style: {
type: String,
default: ''
},
//
contentStyle: {
type: String,
default: ''
}
})
//
const emit = defineEmits(['close'])
//
const handleClose = () => {
emit('close')
}
</script>
<template>
<!-- 遮罩层容器 -->
<div
v-if="visible"
class="mask"
@click.self="handleClose"
:style="style"
>
<div class="mask-content" :style="contentStyle">
<!-- 插槽用于插入自定义内容 -->
<slot></slot>
</div>
</div>
</template>
<style scoped>
.mask {
/* 固定定位,覆盖整个屏幕 */
position: fixed;
inset: 0;
/* 半透明黑色背景 */
background-color: rgba(0, 0, 0, 0.5);
/* 层级设置 */
z-index: 1000;
/* 弹性布局,使内容居中 */
/* 添加过渡效果 */
display: flex;
justify-content: center;
align-items: flex-start;
transition: opacity 0.3s ease;
}
.mask-content {
/* 背景色 */
background-color: #fff;
/* 边框圆角 */
border-radius: 8px;
/* 内边距 */
padding: 24px;
/* 阴影效果 */
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
/* 最大宽度 */
max-width: 700px;
/* 最小宽度 */
min-width: 300px;
/* 最大高度 */
height: auto;
display: inline-block;
max-height: 80vh;
/* 超出内容滚动 */
overflow-y: auto;
margin-top: 5%;
}
</style>

@ -6,8 +6,9 @@ import Map from "@/components/about/Map.vue";
//
const bmapRef = ref(null);
//
const mapCenter = ref({ lng: 116.372326, lat: 39.991868});
//116.365873,39.985891
const mapCenter = ref({ lng: 116.371127, lat: 39.992468});
const mapMark = ref({ lng: 116.372326, lat: 39.991868});
// 116.365873,39.985891
//
onMounted(() => {
//
@ -17,16 +18,16 @@ onMounted(() => {
const mapInstance = bmapRef.value.getMap();
//
const point = new window.BMap.Point(mapCenter.value.lng, mapCenter.value.lat);
const point = new window.BMap.Point(mapMark.value.lng, mapMark.value.lat);
const marker = bmapRef.value.addMarker(point);
//
bmapRef.value.openInfoWindow("飞利信大厦<br>地址北京市海淀区塔院志新村2号", point);
//
marker.addEventListener("click", () => {
bmapRef.value.openInfoWindow("飞利信大厦<br>地址北京市海淀区塔院志新村2号", point);
});
// //
// bmapRef.value.openInfoWindow("<br>2", point);
//
// //
// marker.addEventListener("click", () => {
// bmapRef.value.openInfoWindow("<br>2", point);
// });
}
}, 100);
});

@ -1,5 +1,5 @@
<script setup>
import { ref, computed } from 'vue'; //
import {ref, computed, onBeforeUnmount} from 'vue'; //
import DynamicItem from "@/components/about/DynamicItem.vue";
import {ArrowLeftBold, ArrowRightBold} from "@element-plus/icons-vue";
@ -39,6 +39,16 @@ const next = () => {
carouselRef.value.next()
}
}
//
onBeforeUnmount(() => {
if (carouselRef.value) {
//
carouselRef.value.setActiveItem= 0;
}
});
</script>
<template>
@ -58,7 +68,7 @@ const next = () => {
<!-- 遍历当前组内的每个项目渲染DynamicItem组件 -->
<DynamicItem
v-for="item in group"
:key="item.title"
:key="item.id"
:imgUrl="item.imgUrl"
:title="item.title"
:content="item.content"
@ -121,7 +131,7 @@ const next = () => {
.item-container {
display: flex;
justify-content: space-between;
background-color: #ffffffff;
background-color: #ffffff;
}
}
</style>

@ -1,7 +1,7 @@
<script setup>
import {ArrowLeftBold, ArrowRightBold} from "@element-plus/icons-vue";
import {computed, ref} from "vue";
import {computed, onBeforeUnmount, ref} from "vue";
import HonorItem from "@/components/about/HonorItem.vue";
const props=defineProps({
@ -39,6 +39,15 @@ const next = () => {
carouselRef.value.next()
}
}
//
onBeforeUnmount(() => {
if (carouselRef.value) {
//
carouselRef.value = null;
}
});
</script>
<template>
@ -52,7 +61,7 @@ const next = () => {
<div class="item-container">
<HonorItem
v-for="(item,index) in group"
:key=index
:key=item.id
:time="item.time"
:image="item.image"
:label="item.label" />

@ -75,7 +75,7 @@ watch(() => props.zoom, (newZoom) => {
onBeforeUnmount(() => {
if (map.value) {
map.value.clearOverlays();
map.value.removeEventListener();
// map.value.removeEventListener();
map.value = null;
}
});
@ -106,9 +106,28 @@ defineExpose({
</script>
<template>
<div ref="mapContainer" :style="{ width, height }"></div>
<div class="map" ref="mapContainer" :style="{ width, height }"></div>
</template>
<style scoped>
/* 地图容器样式 */
.map{
:deep(.BMap_stdMpCtrl){
inset:0 0 auto auto !important;
}
:deep(.BMap_stdMpPan){
display: none;
}
:deep(.BMap_stdMpSlider){
display: none;
height: 0 !important;
}
:deep(.BMap_stdMpZoomOut){
top: 30px !important;
}
:deep(.BMap_zlHolder.hvr){
display: none;
}
}
</style>

@ -1,15 +1,42 @@
// 导出获取图片URL的函数
export const getImageUrl = (path) => {
// 如果是绝对URL直接返回
// 如果path不存在或不是字符串直接返回空字符串
if (!path || typeof path !== 'string') {
console.error('getImageUrl: path 参数无效或为空', path);
return '';
}
// 如果是绝对URLhttp://或https://开头),直接返回
if (path.startsWith('http://') || path.startsWith('https://')) {
return path
return path;
}
// 否则处理为本地资源
// 使用Vite支持的动态导入方式
try {
// return new URL(`/src/assets/${path}`, import.meta.url).href
return `/src/assets/${path}`
// 根据不同的图片路径返回对应的导入URL
// 注意:这种方式需要为每个图片路径单独添加映射
// 您可以根据实际需要扩展这个映射表
const imageMap = {
'img/honor1.png': new URL('../assets/img/honor1.png', import.meta.url).href,
'img/honor2.png': new URL('../assets/img/honor2.png', import.meta.url).href,
'img/honor3.png': new URL('../assets/img/honor3.png', import.meta.url).href,
'img/dynamic1.png': new URL('../assets/img/dynamic1.png', import.meta.url).href,
'img/dynamic2.png': new URL('../assets/img/dynamic2.png', import.meta.url).href,
// 可以根据需要添加更多图片路径映射
};
// 如果找到对应的映射返回映射的URL
if (imageMap[path]) {
return imageMap[path];
} else {
// 如果没有找到映射,尝试使用默认方式
console.warn('图片路径未在映射表中找到:', path);
return new URL(`../assets/${path}`, import.meta.url).href;
}
} catch (error) {
console.error('图片加载失败:', error)
return ''
// 如果构建失败,打印错误信息并返回空字符串
console.error('图片加载失败:', error, '路径:', path);
return '';
}
}

@ -1,11 +1,14 @@
<script setup>
import {ref} from "vue";
import {ref, watch} from "vue";
import AboutProfile from "@/components/about/AboutProfile.vue";
import AboutDynamic from "@/components/about/AboutDynamic.vue";
import AboutHonor from "@/components/about/AboutHonor.vue";
import AboutContactUs from "@/components/about/AboutContactUs.vue";
const activeName = ref('first')
// ref
const aboutDynamicRef = ref(null);
const aboutHonorRef = ref(null);
const dynamicData = ref([
@ -13,86 +16,102 @@ const dynamicData = ref([
imgUrl: "img/dynamic1.png",
title: "端侧AI降噪模组设计",
content: "专为语音收集和处理设计的USB AI降噪麦克风模组这是一款基于XMOS XU316芯片和Codec芯片的专业音频处理模组。",
time: "2023-01-01"
time: "2023-01-01",
id:100001,
},
{
imgUrl: "img/dynamic2.png",
title: "AI降噪产品化市场环境",
content: "当前AI降噪市场已形成结构清晰、协同发展的三层产业链格局",
time: "2023-01-01"
time: "2023-01-01",
id:100002,
},
{
imgUrl: "img/dynamic1.png",
title: "端侧AI降噪模组设计",
content: "专为语音收集和处理设计的USB AI降噪麦克风模组这是一款基于XMOS XU316芯片和Codec芯片的专业音频处理模组。",
time: "2023-01-01"
time: "2023-01-01",
id:100003,
},
{
imgUrl: "img/dynamic1.png",
title: "端侧AI降噪模组设计",
content: "专为语音收集和处理设计的USB AI降噪麦克风模组这是一款基于XMOS XU316芯片和Codec芯片的专业音频处理模组。",
time: "2023-01-01"
time: "2023-01-01",
id:100004,
}
])
const honorData = ref([
{
id:10001,
time: "2022年",
image: "img/honor1.png",
label: "xxxx比赛金奖"
},
{
id:10002,
time: "2022年",
image: "img/honor2.png",
label: "国家高新技术企业"
},
{
id:10003,
time: "2022年",
image: "img/honor3.png",
label: "国家高新技术企业"
},
{
id:10004,
time: "2022年",
image: "img/honor1.png",
label: "国家高新技术企业"
},
{
id:10005,
time: "2022年",
image: "img/honor2.png",
label: "国家高新技术企业"
},
{
id:10006,
time: "2022年",
image: "img/honor3.png",
label: "国家高新技术企业"
},
{
id:10007,
time: "2022年",
image: "img/honor1.png",
label: "xxxx比赛金奖"
},
{
id:10008,
time: "2022年",
image: "img/honor2.png",
label: "国家高新技术企业"
},
{
id:10008,
time: "2022年",
image: "img/honor3.png",
label: "国家高新技术企业"
},
{
id:10009,
time: "2022年",
image: "img/honor1.png",
label: "国家高新技术企业"
},
{
id:10010,
time: "2022年",
image: "img/honor2.png",
label: "国家高新技术企业"
},
{
id:10011,
time: "2022年",
image: "img/honor3.png",
label: "国家高新技术企业"
@ -105,15 +124,15 @@ const honorData = ref([
<div class="header">
<img src="@/assets/img/about-us.png" alt="">
</div>
<el-tabs v-model="activeName" class="about-tabs">
<el-tabs v-model="activeName" class="about-tabs" default-value="first" >
<el-tab-pane label="实验室简介" name="first">
<AboutProfile></AboutProfile>
<AboutProfile></AboutProfile>
</el-tab-pane>
<el-tab-pane label="实验室动态" name="second">
<AboutDynamic :dynamicData="dynamicData"></AboutDynamic>
<AboutDynamic :dynamicData="dynamicData" v-if="activeName==='second'"></AboutDynamic>
</el-tab-pane>
<el-tab-pane label="奖项荣誉" name="third">
<AboutHonor :honorData="honorData"></AboutHonor>
<AboutHonor :honorData="honorData" v-if="activeName==='third'"></AboutHonor>
</el-tab-pane>
<el-tab-pane label="联系我们" name="fourth">
<AboutContactUs></AboutContactUs>

Loading…
Cancel
Save