浏览代码

feat(语言切换): 优化语言切换逻辑和URL参数验证

本次提交主要进行了以下修改:
1. 在 `LanguageSwitcher.vue` 中更新了语言切换逻辑,使用新的URL构建方式替代页面重载,提升用户体验。
2. 在 `products/index.vue` 中添加了URL参数的有效性验证,确保分类和标签参数的正确性,避免无效参数影响页面状态。
3. 更新了路由逻辑,使用 `router.replace` 方法清除无效的分类和标签参数,优化了用户的导航体验。

这些改动旨在提升多语言支持的流畅性和产品页面的可用性。
master
lizhuang 1 个月前
父节点
当前提交
b95826bbdd
共有 2 个文件被更改,包括 106 次插入7 次删除
  1. 11
    1
      components/LanguageSwitcher.vue
  2. 95
    6
      pages/products/index.vue

+ 11
- 1
components/LanguageSwitcher.vue 查看文件

@@ -54,11 +54,13 @@
*/
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
import { useI18n } from "#imports";
import { useRouter } from "vue-router";

// 定义语言代码的类型,应该与 i18n 配置中的一致
type LocaleCode = "zh" | "en" | "ja"; // 你需要根据你的 i18n 配置更新这个类型

const { locale, locales, setLocale } = useI18n();
const router = useRouter();
const currentLocale = computed(() => locale.value);
const isDropdownOpen = ref(false);
const dropdownContainerRef = ref(null);
@@ -88,7 +90,15 @@ async function selectLanguage(langCode: string) {
try {
// 使用类型断言,确保 langCode 是有效的 LocaleCode
await setLocale(langCode as LocaleCode);
window.location.reload();
// 获取当前路径(不包含查询参数)
const path = window.location.pathname;
// 构建新URL,不包含任何查询参数
const newUrl = `${window.location.origin}${path}`;
// 使用新URL替换当前URL并刷新页面
window.location.href = newUrl;
} catch (error) {
console.error("Failed to set locale:", error);
// 这里可以添加用户反馈,例如显示一个错误提示

+ 95
- 6
pages/products/index.vue 查看文件

@@ -176,7 +176,10 @@
</div>

<div
v-if="getCategoryTags(category)?.length > 0 && selectedCategory"
v-if="
getCategoryTags(category)?.length > 0 &&
selectedCategory
"
class="flex flex-wrap gap-4"
>
<span
@@ -691,6 +694,42 @@ watchEffect(() => {
usages.value = uniqueUsages.value;
categories.value = categoryTitles.value;
filteredProducts.value = paginatedProducts.value;

// 验证URL参数中的分类和标签是否有效
if (selectedCategory.value) {
const categoryExists = allCategories.value.some(
(c: Category) => c.title === selectedCategory.value
);

if (!categoryExists) {
// 如果分类不存在于当前语言环境,清除分类和标签参数
selectedCategory.value = "";
selectedTag.value = "all";

// 更新路由,移除无效的参数
router.replace({
query: {
...route.query,
category: undefined,
tag: undefined,
},
});
} else if (selectedTag.value !== "all") {
// 检查标签是否在当前分类中存在
const categoryTags = getCategoryTags(selectedCategory.value);
if (!categoryTags.includes(selectedTag.value)) {
selectedTag.value = "all";

// 更新路由,移除无效的标签参数
router.replace({
query: {
...route.query,
tag: undefined,
},
});
}
}
}
} catch (err) {
console.error("Error processing data:", err);
error.value = new Error(t("products.processError"));
@@ -709,15 +748,15 @@ function handleCategoryFilter(category: string) {
selectedTag.value = "all";
currentPage.value = 1; // 重置页码
filteredProducts.value = paginatedProducts.value;
// 更新路由,移除tag参数
router.push({
query: {
...route.query,
category: category,
tag: undefined, // 清除tag参数
page: currentPage.value > 1 ? currentPage.value.toString() : undefined
}
page: currentPage.value > 1 ? currentPage.value.toString() : undefined,
},
});
}

@@ -760,6 +799,11 @@ watch(selectedUsage, (newValue) => {
watch(
() => route.query,
(newQuery) => {
// 先保存当前的值,方便后续比较变化
const prevCategory = selectedCategory.value;
const prevTag = selectedTag.value;

// 更新本地状态
selectedCategory.value = newQuery.category?.toString() || "";
selectedUsage.value = newQuery.usage?.toString() || "";
selectedTag.value = newQuery.tag?.toString() || "all";
@@ -767,6 +811,51 @@ watch(
if (page !== currentPage.value) {
currentPage.value = page;
}

// 如果数据已加载完成,则验证URL参数的有效性
if (allCategories.value.length > 0 && allProducts.value.length > 0) {
// 检查分类是否有效
if (selectedCategory.value && prevCategory !== selectedCategory.value) {
const categoryExists = allCategories.value.some(
(c: Category) => c.title === selectedCategory.value
);

if (!categoryExists) {
// 如果分类不存在,重置选择并更新路由
selectedCategory.value = "";
selectedTag.value = "all";

// 使用replace而不是push,避免在历史记录中添加新条目
router.replace({
query: {
...route.query,
category: undefined,
tag: undefined,
},
});
return; // 提前退出,因为后续更新将由新的路由触发
}
}

// 检查标签是否有效(仅当有选中分类时)
if (
selectedCategory.value &&
selectedTag.value !== "all" &&
prevTag !== selectedTag.value
) {
const categoryTags = getCategoryTags(selectedCategory.value);
if (!categoryTags.includes(selectedTag.value)) {
selectedTag.value = "all";

router.replace({
query: {
...route.query,
tag: undefined,
},
});
}
}
}
},
{ deep: true }
);
@@ -858,8 +947,8 @@ function selectTag(tag: string) {
router.push({
query: {
...route.query,
tag: tag === "all" ? undefined : tag
}
tag: tag === "all" ? undefined : tag,
},
});
}


正在加载...
取消
保存