LanguageSwitcher.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <template>
  2. <div>
  3. <div class="changeLL">
  4. <div class="changeItem" :class="{ active: currentLang === 'zhCN' }" @click="changeLanguage('zhCN')">
  5. <span class="triangle" v-if="currentLang === 'zhCN'">▶</span>
  6. <span class="text">简体版</span>
  7. </div>
  8. <div class="changeItem" :class="{ active: currentLang === 'zhTW' }" @click="changeLanguage('zhTW')">
  9. <span class="triangle" v-if="currentLang === 'zhTW'">▶</span>
  10. <span class="text">繁體版</span>
  11. </div>
  12. <div class="changeItem" :class="{ active: currentLang === 'en' }" @click="changeLanguage('en')">
  13. <span class="triangle" v-if="currentLang === 'en'">▶</span>
  14. <span class="text">English</span>
  15. </div>
  16. <myNavigation></myNavigation>
  17. </div>
  18. <div class="changeL" ref="changeL">
  19. <el-dropdown
  20. @command="handleCommand"
  21. trigger="click"
  22. placement="bottom-end"
  23. :hide-on-click="true"
  24. :max-height="200"
  25. >
  26. <img src="../../assets/images/net.png" alt="" style="width: 100%;height: 100%; cursor: pointer;">
  27. <template #dropdown>
  28. <el-dropdown-menu>
  29. <el-dropdown-item command="en" :class="{ active: currentLang === 'en' }">EN</el-dropdown-item>
  30. <el-dropdown-item command="zhCN" :class="{ active: currentLang === 'zhCN' }">简体中文</el-dropdown-item>
  31. <el-dropdown-item command="zhTW" :class="{ active: currentLang === 'zhTW' }">繁体中文</el-dropdown-item>
  32. </el-dropdown-menu>
  33. </template>
  34. </el-dropdown>
  35. </div>
  36. </div>
  37. </template>
  38. <script setup>
  39. import { useI18n } from 'vue-i18n';
  40. import { ref, onMounted, onBeforeUnmount } from 'vue';
  41. import myNavigation from "./myNavigation.vue";
  42. const { locale } = useI18n();
  43. // 当前选中的语言
  44. const currentLang = ref('zhCN');
  45. const changeLanguage = (lang) => {
  46. currentLang.value = lang;
  47. locale.value = lang;
  48. // 把当前语言存储到localStorage
  49. localStorage.setItem('language', lang);
  50. // 触发自定义事件,通知其他组件语言已更改
  51. window.dispatchEvent(new CustomEvent('languageChanged', { detail: lang }));
  52. console.log(`语言已切换为: ${lang}`);
  53. // 如果当前的语言是英语,把.nav字体改成Helvetica, Arial, sans-serif
  54. const navElement = document.querySelector('.nav');
  55. if (navElement) {
  56. if (lang === 'en') {
  57. navElement.style.fontFamily = 'Helvetica, Arial, sans-serif';
  58. } else {
  59. navElement.style.fontFamily = "'Source Han Sans CN', 'Source Han Sans SC', 'Noto Sans CJK SC', 'Noto Sans SC', 'SimHei', 'Microsoft YaHei', 'Heiti SC', 'PingFang SC', 'WenQuanYi Micro Hei', 'Helvetica Neue', Helvetica, Arial, sans-serif";
  60. }
  61. }
  62. };
  63. const changeL = ref(null);
  64. // 监听页面宽度
  65. const screenWidth = ref(window.innerWidth); // 初始化屏幕宽度
  66. // 响应式处理函数
  67. const handleResize = () => {
  68. screenWidth.value = window.innerWidth;
  69. // 当页面宽度小于768时,隐藏类名是changeItem的div
  70. if (screenWidth.value < 768) {
  71. // 获取类名是changeItem的全部div
  72. document.querySelectorAll('.changeItem').forEach(item => {
  73. item.style.display = 'none'
  74. });
  75. document.querySelector('.changeLL').style.display = 'none';
  76. // 安全检查changeL.value是否存在
  77. if (changeL.value) {
  78. changeL.value.style.display = 'block'
  79. } else {
  80. console.warn('changeL元素未找到');
  81. }
  82. } else {
  83. // 安全检查changeL.value是否存在
  84. if (changeL.value) {
  85. changeL.value.style.display = 'none';
  86. }
  87. document.querySelectorAll('.changeItem').forEach(item => {
  88. item.style.display = 'block'
  89. });
  90. }
  91. };
  92. // 使用addEventListener而不是直接赋值
  93. const resizeListener = () => {
  94. handleResize();
  95. };
  96. const handleCommand = (command) => {
  97. console.log('下拉菜单选择:', command);
  98. changeLanguage(command);
  99. }
  100. onMounted(() => {
  101. // 从 localStorage 读取保存的语言设置
  102. const savedLanguage = localStorage.getItem('language') || 'zhCN';
  103. currentLang.value = savedLanguage;
  104. locale.value = savedLanguage;
  105. // 如果当前的语言是英语,把.nav字体改成Helvetica, Arial, sans-serif
  106. const navElement = document.querySelector('.nav');
  107. if (navElement) {
  108. if (savedLanguage === 'en') {
  109. navElement.style.fontFamily = 'Helvetica, Arial, sans-serif';
  110. } else {
  111. navElement.style.fontFamily = "'Source Han Sans CN', 'Source Han Sans SC', 'Noto Sans CJK SC', 'Noto Sans SC', 'SimHei', 'Microsoft YaHei', 'Heiti SC', 'PingFang SC', 'WenQuanYi Micro Hei', 'Helvetica Neue', Helvetica, Arial, sans-serif";
  112. }
  113. }
  114. console.log(`初始化语言: ${savedLanguage}`);
  115. // 延迟执行响应式处理,避免与dropdown初始化冲突
  116. // setTimeout(() => {
  117. // 添加resize监听器
  118. window.addEventListener('resize', resizeListener);
  119. // 初始化响应式处理
  120. handleResize();
  121. // }, 100);
  122. });
  123. // 组件卸载时清理事件监听器
  124. onBeforeUnmount(() => {
  125. window.removeEventListener('resize', resizeListener);
  126. });
  127. </script>
  128. <style scoped>
  129. .changeL {
  130. width: 4rem;
  131. height: 4rem;
  132. }
  133. /* dropdown菜单样式 */
  134. :deep(.el-dropdown-menu) {
  135. min-width: 120px !important;
  136. .el-dropdown-menu__item {
  137. padding: 8px 16px;
  138. &.active {
  139. color: #F7B334;
  140. background-color: #fff7e6;
  141. }
  142. &:hover {
  143. background-color: #f5f5f5;
  144. }
  145. }
  146. }
  147. .changeItem {
  148. cursor: pointer;
  149. color:#999;
  150. font-size:1.2rem;
  151. line-height: 2.8rem;
  152. }
  153. .changeItem.active {
  154. color: #F7B334;
  155. }
  156. /* 橘色三角形样式 */
  157. .triangle {
  158. color: #F7B334;
  159. font-size: 0.9rem;
  160. display: inline-block;
  161. /* animation: slideIn 0.3s ease-in-out; */
  162. margin-right:5px
  163. }
  164. /* 三角形出现动画 */
  165. /* @keyframes slideIn {
  166. from {
  167. opacity: 0;
  168. transform: translateX(10px);
  169. }
  170. to {
  171. opacity: 1;
  172. transform: translateX(0);
  173. }
  174. } */
  175. /* 文字部分 */
  176. .text {
  177. display: inline-block;
  178. text-align: center;
  179. /* transition: all 0.3s ease; */
  180. }
  181. .changeLL {
  182. width: 100%;
  183. display: flex;
  184. gap: 10px;
  185. justify-content: flex-end;
  186. }
  187. </style>