header.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <template>
  2. <header>
  3. <div class="header--wrap" :class="{ 'white': isScrolled || isMobileMenuOpen }">
  4. <div class="header--container">
  5. <NuxtLink class="logo--wrap" to="/">그린웨일글로벌</NuxtLink>
  6. <ul class="menu--wrap">
  7. <li class="menu--item">
  8. <NuxtLink to="/company/intro">Company</NuxtLink>
  9. <ul class="gnb--wrap">
  10. <li><NuxtLink to="/company/intro">회사소개</NuxtLink></li>
  11. <li><NuxtLink to="/company/history">회사연혁</NuxtLink></li>
  12. <li><NuxtLink to="/company/partners">협력업체</NuxtLink></li>
  13. <li><NuxtLink to="/company/catalog">회사소개자료</NuxtLink></li>
  14. </ul>
  15. </li>
  16. <li class="menu--item">
  17. <NuxtLink to="/products/materials">Products</NuxtLink>
  18. <ul class="gnb--wrap">
  19. <li><NuxtLink to="/products/materials">Materials</NuxtLink></li>
  20. <li><NuxtLink to="/products/solutions">Solutions</NuxtLink></li>
  21. </ul>
  22. </li>
  23. <li class="menu--item">
  24. <NuxtLink to="/technology/facilities">Technology</NuxtLink>
  25. <ul class="gnb--wrap">
  26. <li><NuxtLink to="/technology/facilities">시설</NuxtLink></li>
  27. <li><NuxtLink to="/technology/patents">특허 / 인증</NuxtLink></li>
  28. </ul>
  29. </li>
  30. <li class="menu--item">
  31. <NuxtLink to="/media/news">Media</NuxtLink>
  32. <ul class="gnb--wrap">
  33. <li><NuxtLink to="/media/news">환경뉴스</NuxtLink></li>
  34. <li><NuxtLink to="/media/press">보도자료</NuxtLink></li>
  35. </ul>
  36. </li>
  37. <li class="menu--item">
  38. <NuxtLink to="/contact/notice">Contact</NuxtLink>
  39. <ul class="gnb--wrap">
  40. <li><NuxtLink to="/contact/notice">공지사항</NuxtLink></li>
  41. <li><NuxtLink to="/contact/faq">FAQ</NuxtLink></li>
  42. <li><NuxtLink to="/contact/support">고객센터</NuxtLink></li>
  43. <li><NuxtLink to="/contact/location">오시는길</NuxtLink></li>
  44. </ul>
  45. </li>
  46. </ul>
  47. <div class="lang--wrap" :class="{ 'active': isLangOpen }" @click="toggleLang" ref="langWrap">
  48. <i class="ico"></i>
  49. <p>KR</p>
  50. <ul class="select--wrap">
  51. <li>Arabic</li>
  52. <li>Chinese (Simplified)</li>
  53. <li>Chinese (Traditional)</li>
  54. <li>English</li>
  55. <li>Esperanto</li>
  56. <li>French</li>
  57. </ul>
  58. </div>
  59. <div class="ham--wrap" :class="{ 'active': isMobileMenuOpen }">
  60. <UButton @click="toggleMobileMenu"></UButton>
  61. </div>
  62. </div>
  63. </div>
  64. <div class="mobile--header--wrap" :class="{ 'active': isMobileMenuOpen }">
  65. <div class="mobile--menu--wrap">
  66. <ul>
  67. <li>
  68. <div @click="toggleAccordion('company')" :class="{ 'active': activeAccordion === 'company' }">
  69. Company<i class="ico"></i>
  70. </div>
  71. <ul :class="{ 'active': activeAccordion === 'company' }">
  72. <li><NuxtLink to="/company/intro">회사소개</NuxtLink></li>
  73. <li><NuxtLink to="/company/history">회사연혁</NuxtLink></li>
  74. <li><NuxtLink to="/company/partners">협력업체</NuxtLink></li>
  75. <li><NuxtLink to="/company/catalog">회사소개자료</NuxtLink></li>
  76. </ul>
  77. </li>
  78. <li>
  79. <div @click="toggleAccordion('products')" :class="{ 'active': activeAccordion === 'products' }">
  80. Products<i class="ico"></i>
  81. </div>
  82. <ul :class="{ 'active': activeAccordion === 'products' }">
  83. <li><NuxtLink to="/products/materials">Materials</NuxtLink></li>
  84. <li><NuxtLink to="/products/solutions">Solutions</NuxtLink></li>
  85. </ul>
  86. </li>
  87. <li>
  88. <div @click="toggleAccordion('technology')" :class="{ 'active': activeAccordion === 'technology' }">
  89. Technology<i class="ico"></i>
  90. </div>
  91. <ul :class="{ 'active': activeAccordion === 'technology' }">
  92. <li><NuxtLink to="/technology/facilities">시설</NuxtLink></li>
  93. <li><NuxtLink to="/technology/patents">특허 / 인증</NuxtLink></li>
  94. </ul>
  95. </li>
  96. <li>
  97. <div @click="toggleAccordion('media')" :class="{ 'active': activeAccordion === 'media' }">
  98. Media<i class="ico"></i>
  99. </div>
  100. <ul :class="{ 'active': activeAccordion === 'media' }">
  101. <li><NuxtLink to="/media/news">환경뉴스</NuxtLink></li>
  102. <li><NuxtLink to="/media/press">보도자료</NuxtLink></li>
  103. </ul>
  104. </li>
  105. <li>
  106. <div @click="toggleAccordion('contact')" :class="{ 'active': activeAccordion === 'contact' }">
  107. Contact<i class="ico"></i>
  108. </div>
  109. <ul :class="{ 'active': activeAccordion === 'contact' }">
  110. <li><NuxtLink to="/contact/notice">공지사항</NuxtLink></li>
  111. <li><NuxtLink to="/contact/faq">FAQ</NuxtLink></li>
  112. <li><NuxtLink to="/contact/support">고객센터</NuxtLink></li>
  113. <li><NuxtLink to="/contact/location">오시는길</NuxtLink></li>
  114. </ul>
  115. </li>
  116. </ul>
  117. </div>
  118. <div class="mobile--lang--wrap">
  119. <div class="lang--wrap" :class="{ 'active': isLangOpen2 }" @click="toggleLang2" ref="langWrap2">
  120. <i class="ico"></i>
  121. <p>KR</p>
  122. <ul class="select--wrap">
  123. <li>Arabic</li>
  124. <li>Chinese (Simplified)</li>
  125. <li>Chinese (Traditional)</li>
  126. <li>English</li>
  127. <li>Esperanto</li>
  128. <li>French</li>
  129. </ul>
  130. </div>
  131. </div>
  132. </div>
  133. </header>
  134. </template>
  135. <script setup>
  136. import { ref, onMounted, onUnmounted } from 'vue'
  137. const isScrolled = ref(false)
  138. const isLangOpen = ref(false)
  139. const isLangOpen2 = ref(false)
  140. const isMobileMenuOpen = ref(false)
  141. const activeAccordion = ref(null)
  142. const langWrap = ref(null)
  143. const langWrap2 = ref(null)
  144. const handleScroll = () => {
  145. // 모바일 메뉴가 열려있으면 스크롤 위치와 상관없이 white 클래스 유지
  146. if (isMobileMenuOpen.value) {
  147. isScrolled.value = true
  148. } else {
  149. isScrolled.value = window.scrollY > 0
  150. }
  151. }
  152. const toggleLang = () => {
  153. isLangOpen.value = !isLangOpen.value
  154. }
  155. const toggleLang2 = () => {
  156. isLangOpen2.value = !isLangOpen2.value
  157. }
  158. const toggleMobileMenu = () => {
  159. isMobileMenuOpen.value = !isMobileMenuOpen.value;
  160. }
  161. const toggleAccordion = (section) => {
  162. if (activeAccordion.value === section) {
  163. activeAccordion.value = null
  164. } else {
  165. activeAccordion.value = section
  166. }
  167. }
  168. const handleClickOutside = (event) => {
  169. if (langWrap.value && !langWrap.value.contains(event.target)) {
  170. isLangOpen.value = false
  171. }
  172. }
  173. const handleClickOutside2 = (event) => {
  174. if (langWrap2.value && !langWrap2.value.contains(event.target)) {
  175. isLangOpen2.value = false
  176. }
  177. }
  178. onMounted(() => {
  179. window.addEventListener('scroll', handleScroll)
  180. document.addEventListener('click', handleClickOutside)
  181. document.addEventListener('click', handleClickOutside2)
  182. })
  183. onUnmounted(() => {
  184. window.removeEventListener('scroll', handleScroll)
  185. document.removeEventListener('click', handleClickOutside)
  186. document.removeEventListener('click', handleClickOutside2)
  187. })
  188. </script>