本地化(国际化)
VueToCounter 提供了本地化功能,用于处理数字和时间间隔的本地化。
VueToCounterNumber 和 VueToCounterDatetimeDuration 组件支持本地化,你可以通过 locale
属性来设置本地化的配置。
大多数情况下,你只需要将 locale
属性设置为 语言代码(如 en
,en-US
,zh
,zh-CN
)即可。 VueToCounter 内部将调用 Intl API 来处理本地化。
时间间隔本地化
~
点击查看代码
vue
<script setup>
import { ref } from "vue";
import LocaleSelect from "./LocaleSelect.vue";
const from = ref("2024-12-01T00:00:00");
const to = ref("2024-12-31T00:00:00");
function switchDatetime() {
[from.value, to.value] = [to.value, from.value];
}
const locale = ref(navigator.language);
</script>
<template>
<div class="text-center">
<vue-to-counter-datetime-duration :value="[from, to]" :locale="locale" />
</div>
<hr />
<div class="flex gap-4">
<div>
<input
class="border border-solid p-1"
v-model="from"
type="datetime-local"
/>
~
<input
class="border border-solid p-1"
v-model="to"
type="datetime-local"
/>
</div>
<button class="border border-solid p-1" @click="switchDatetime">
切换
</button>
<span class="flex-auto" />
<locale-select
class="border border-solid p-1 appearance-auto"
v-model="locale"
/>
</div>
</template>
<style scoped></style>
vue
<script setup>
const value = defineModel("modelValue");
</script>
<template>
<select class="border border-solid p-1 appearance-auto" v-model="value">
<optgroup label="中文">
<option value="zh-CN">zh-CN</option>
<option value="zh-HK">zh-HK</option>
<option value="zh-TW">zh-TW</option>
</optgroup>
<optgroup label="English">
<option value="en-US">en-US</option>
<option value="en-GB">en-GB</option>
</optgroup>
<option value="ja-JP">ja-JP</option>
<option value="ko-KR">ko-KR</option>
<option value="de-DE">de-DE</option>
<option value="fr-FR">fr-FR</option>
</select>
</template>
<style scoped></style>
vue
<script setup>
import StackblitzLogo from "../assets/stackblitz-logo.svg";
import { ref, toRefs } from "vue";
import { getCodeStackblitzParams } from "./generate-stackblitz-params";
import sdk from "@stackblitz/sdk";
import packageInfo from "../../vue-to-counter/package.json";
const props = defineProps({
title: {
type: String,
required: true,
},
});
const { title } = toRefs(props);
const containerRef = ref();
function handleStackblitz() {
if (!containerRef.value) return;
const tabs = containerRef.value.querySelectorAll(".tabs > label");
const blocks = containerRef.value.querySelectorAll(".blocks > div code");
if (tabs.length !== blocks.length) {
window.alert("The number of tabs and code blocks should be the same.");
return;
}
const files = Array.from(tabs).map((tab, index) => ({
filename: tab.textContent.trim(),
content: blocks[index].textContent,
}));
const params = getCodeStackblitzParams(files, {
title: `${title.value} - vue-to-counter@${packageInfo.version}`,
});
sdk.openProject(params, {
openFile: "src/demo.vue",
});
}
</script>
<template>
<div ref="containerRef" class="demo-container">
<div class="flex relative">
<span class="flex-auto" />
<span
title="Open In Stackblitz"
class="inline-block p-1 cursor-pointer hover:outline hover:outline-[#1389FD] outline-1"
@click="handleStackblitz"
>
<img
class="h-4 w-4 pointer-events-none"
:src="StackblitzLogo"
alt="CodeSandbox Logo"
/>
</span>
</div>
<hr />
<slot />
</div>
</template>
<style lang="scss">
.demo-container {
@apply flex flex-col justify-center border p-4 rounded-lg mt-4 text-sm;
.vue-to-counter {
@apply font-mono text-4xl;
}
.custom-block {
@apply m-0;
}
}
</style>
数字本地化
特别的,VueToCounterNumber
组件还需要设置 locale-number
属性。
- 你可以将其设置为
true
,这将使用默认配置启用数字本地化。 - 也可以设置为 Intl.NumberFormat 支持的选项。
0110110440,,055011044
点击查看代码
vue
<script setup>
import { ref } from "vue";
import LocaleSelect from "./LocaleSelect.vue";
const number = ref(114514);
function switchNumber() {
number.value = Math.floor(Math.random() * 1000000);
}
const locale = ref(navigator.language);
</script>
<template>
<div class="text-center">
<vue-to-counter-number :value="number" :locale="locale" locale-number />
</div>
<hr />
<div class="flex gap-4">
<input class="border border-solid p-1" v-model="number" type="number" />
<button class="border border-solid p-1" @click="switchNumber">切换</button>
<span class="flex-auto" />
<locale-select
class="border border-solid p-1 appearance-auto"
v-model="locale"
/>
</div>
</template>
<style scoped></style>
vue
<script setup>
const value = defineModel("modelValue");
</script>
<template>
<select class="border border-solid p-1 appearance-auto" v-model="value">
<optgroup label="中文">
<option value="zh-CN">zh-CN</option>
<option value="zh-HK">zh-HK</option>
<option value="zh-TW">zh-TW</option>
</optgroup>
<optgroup label="English">
<option value="en-US">en-US</option>
<option value="en-GB">en-GB</option>
</optgroup>
<option value="ja-JP">ja-JP</option>
<option value="ko-KR">ko-KR</option>
<option value="de-DE">de-DE</option>
<option value="fr-FR">fr-FR</option>
</select>
</template>
<style scoped></style>
vue
<script setup>
import StackblitzLogo from "../assets/stackblitz-logo.svg";
import { ref, toRefs } from "vue";
import { getCodeStackblitzParams } from "./generate-stackblitz-params";
import sdk from "@stackblitz/sdk";
import packageInfo from "../../vue-to-counter/package.json";
const props = defineProps({
title: {
type: String,
required: true,
},
});
const { title } = toRefs(props);
const containerRef = ref();
function handleStackblitz() {
if (!containerRef.value) return;
const tabs = containerRef.value.querySelectorAll(".tabs > label");
const blocks = containerRef.value.querySelectorAll(".blocks > div code");
if (tabs.length !== blocks.length) {
window.alert("The number of tabs and code blocks should be the same.");
return;
}
const files = Array.from(tabs).map((tab, index) => ({
filename: tab.textContent.trim(),
content: blocks[index].textContent,
}));
const params = getCodeStackblitzParams(files, {
title: `${title.value} - vue-to-counter@${packageInfo.version}`,
});
sdk.openProject(params, {
openFile: "src/demo.vue",
});
}
</script>
<template>
<div ref="containerRef" class="demo-container">
<div class="flex relative">
<span class="flex-auto" />
<span
title="Open In Stackblitz"
class="inline-block p-1 cursor-pointer hover:outline hover:outline-[#1389FD] outline-1"
@click="handleStackblitz"
>
<img
class="h-4 w-4 pointer-events-none"
:src="StackblitzLogo"
alt="CodeSandbox Logo"
/>
</span>
</div>
<hr />
<slot />
</div>
</template>
<style lang="scss">
.demo-container {
@apply flex flex-col justify-center border p-4 rounded-lg mt-4 text-sm;
.vue-to-counter {
@apply font-mono text-4xl;
}
.custom-block {
@apply m-0;
}
}
</style>