123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- <script setup lang="ts">
- import { useRouter, useRoute } from 'vue-router';
- defineProps<{
- state: string
- }>()
- const emit = defineEmits(['onDrawer', 'onModal']);
- const { t } = useI18n();
- const menuData = [
- {
- name: "首页",
- langKey: 'menu.home',
- path: '/',
- children: [],
- },
- {
- name: 'LibraAI大模型',
- langKey: 'menu.aiModel',
- path: '/ai/model',
- model: 'ai',
- children: [
- {
- label: 'LibraAI大模型',
- langKey: 'menu.aiModelSubVertica',
- key: '/ai/model'
- },
- {
- label: 'LibraAl水务大模型',
- langKey: 'menu.aiModelSubWater',
- key: '/ai/water'
- }
- ],
- },
- {
- name: 'Libra碳中和',
- langKey: 'menu.libraCarbonNeutral',
- path: '/carbon/dmrv',
- model: 'carbon',
- children: [
- {
- label: '碳资产开发交易',
- langKey: 'menu.libraCarbonNeutralSubDevelopment',
- key: '/carbon/dmrv'
- },
- {
- label: '可持续发展',
- langKey: 'menu.libraCarbonNeutralSubSustainable',
- key: '/carbon/develop'
- }
- ],
- },
- {
- name: '新闻中心',
- langKey: 'menu.news',
- path: '/news',
- children: [],
- },
- {
- name: '关于我们',
- langKey: 'menu.about',
- path: '/about',
- children: [],
- },
- ]
- const router = useRouter();
- const route = useRoute();
- const { locale, setLocale } = useI18n();
- const headerDomRef = ref(null);
- const dropdownState = ref({ai: false, carbon: false});
- const activeLangKey = ref(unref(locale));
- const isAiModel = computed(() => route.path.includes("/ai/model"));
- const menuActiveClassName = computed(() => !isAiModel.value ? "primary-active" : "ai-active");
- const changeLanguage = (lang: 'zh' | 'en') => {
- activeLangKey.value = lang;
- setLocale(lang);
- }
- const handelOpenDrawer = () => {
- emit('onDrawer');
- }
- const handelOpenModal = () => {
- emit('onModal');
- }
- const renderDropdownLabel = (option) => {
- return h('span', [t(option.langKey)]);
- }
- // dropdown 状态变更
- const handleUpdateState = (state: boolean, stateKey: 'ai'|'carbon' ) => {;
- if ( stateKey === 'ai' || stateKey === 'carbon' ) {
- dropdownState.value[stateKey] = state;
- }
- }
- // menu
- const handleMenuClick = (path: string) => {
- if (path) router.push(path);
- }
- // menu - options
- const handleSelect = (path: string) => {
- router.push(path);
- }
- // logo
- const goBackHome = () => {
- router.push('/')
- }
- </script>
- <template>
- <section class="nav-bar_container h-[70px] px-[10px] lg:px-[40px] lg:h-[70px] md:max-lg:px-[5px]"
- :class="[state, { 'dropdown': dropdownState.ai || dropdownState.carbon }, { 'ai-header': isAiModel }]" ref="headerDomRef">
- <h1 class="logo w-[89px] md:w-[89px]" @click="goBackHome"></h1>
- <div class="hidden md:block">
- <ul class="menu-list">
- <li :class="['menu-item', { [menuActiveClassName]: item.path === route.path }]" v-for="item, index in menuData" :key="index" @click="handleMenuClick(item.path)">
- <span class="block h-full" v-if="!item.children.length">{{ $t(item.langKey) }}</span>
- <n-dropdown
- class="menu-popover-container"
- trigger="hover"
- placement="bottom-start"
- :render-label="renderDropdownLabel"
- :show-arrow="false"
- :on-update:show="state => handleUpdateState(state, item.model as 'ai' | 'carbon')"
- :options="item.children"
- :duration="200"
- @select="handleSelect"
- v-else
- >
- <span class="block h-full">{{ $t(item.langKey) }}</span>
- </n-dropdown>
- </li>
- </ul>
- </div>
- <ul class="translation-container">
- <li class="mr-[10px] lg:mr-[50px] lg:block">
- <div class="contract-btn w-[98px] h-[28px] lg:w-[98px] lg:h-[36px]" @click="handelOpenModal">
- <span>{{ $t('menu.contractBtnVal') }}</span>
- </div>
- <!-- <div class="flex items-center">
- <nuxt-icon name="icon-phone" class="mr-[6px] text-[20px]" />
- <span>010-63366692</span>
- </div> -->
- </li>
- <li class="hidden md:block">
- <p class="lang-switch">
- <span :class="{ active: activeLangKey === 'zh' }" @click="changeLanguage('zh')">中</span>
- <span class="active px-[5px]"> / </span>
- <span :class="{ active: activeLangKey === 'en' }" @click="changeLanguage('en')">En</span>
- </p>
- </li>
- <li class="block md:hidden ml-[20px]" @click="handelOpenDrawer">
- <p class="moble-menu-btn">
- <span class="line"></span>
- <span class="line"></span>
- <span class="line"></span>
- </p>
- </li>
- </ul>
- </section>
- </template>
- <style scoped lang="scss">
- $text-color-primary: #161616;
- .moble-menu-btn {
- @include flex(y, center, around);
- width: 16px;
- height: 16px;
- .line {
- width: 100%;
- height: 2px;
- background: #191a24;
- }
- }
- @mixin nav-parmary-active {
- background: #fff;
- color: $text-color-primary;
- .logo {
- background: url('@/assets/image/header/logo-color.png') no-repeat;
- background-size: 100% 100%;
- }
- .active {
- color: $text-color-primary;
- }
- }
- .nav-bar_container {
- position: fixed;
- top: 0;
- left: 0;
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- z-index: 100;
- // transition: all .3s;
- overflow: hidden;
- white-space: nowrap;
- transition: background-color 0.3s;
- color: #fff;
- .logo {
- height: 36px;
- cursor: pointer;
- background: url('@/assets/image/header/logo-white.png') no-repeat;
- background-size: 100% 100%;
- }
- .menu-list {
- height: 70px;
- @include flex(x, center, center);
- .menu-item {
- height: 100%;
- font-weight: 400;
- cursor: pointer;
- line-height: 70px;
- &:not(:last-child) {
- font-size: 14px;
- margin-right: 40px;
- }
- }
- }
- .translation-container {
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 14px;
- .contract-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 8px;
- background: linear-gradient(87.67deg, #2A67F8 4.95%, #4892FF 93.07%);
- font-size: 14px;
- line-height: 14px;
- color: #fff !important;
- cursor: pointer;
- }
- li:nth-child(1) {
- font-size: 14px;
- font-weight: 600;
- }
- .active {
- color: #fff;
- }
- }
- &:hover {
- @include nav-parmary-active;
- .primary-active {
- span {
- color: #2A68FF !important;
- }
- }
- .ai-active {
- span {
- color: #2A68FF;
- }
- }
- }
- }
- .lang-switch {
- font-size: 14px;
- color: #CECCCB;
- &:nth-child(1),
- &:nth-child(3) {
- cursor: pointer;
- }
- }
- .dropdown {
- @include nav-parmary-active;
- .lang-switch .active {
- color: $text-color-primary;
- }
- .primary-active {
- span {
- color: #2A68FF !important;
- }
- }
- .ai-active {
- span {
- color: #2A68FF;
- }
- }
- }
- .primary-active,
- .ai-active {
- span {
- font-weight: bold;
- }
- }
- .up {
- .active {
- color: #fff;
- }
- }
- .down {
- @include nav-parmary-active;
- box-shadow: 0px 4px 10px 0px #565F830D;
- .lang-switch .active {
- color: $text-color-primary;
- }
- .primary-active {
- span {
- color: #2A68FF;
- }
- }
- .ai-active {
- span {
- color: #2A68FF;
- }
- }
- }
- .ai-header {
- color: $text-color-primary;
- .logo {
- background: url('@/assets/image/header/logo-color.png') no-repeat;
- background-size: 100% 100%;
- }
- .lang-switch .active {
- color: $text-color-primary;
- }
- .lang-switch {
- color: #8B8B8B;
- }
- }
- </style>
- <style>
- svg {
- margin: 0 !important;
- }
- .menu-popover-container {
- margin-top: 0px !important;
- /* padding: 14px 10px !important; */
- }
- </style>
|