Skip to content

Commit

Permalink
feat: international
Browse files Browse the repository at this point in the history
  • Loading branch information
fewbadboy committed Sep 7, 2024
1 parent 02fa965 commit 52e3cbf
Show file tree
Hide file tree
Showing 15 changed files with 239 additions and 101 deletions.
3 changes: 3 additions & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
ChangeLanguage: typeof import('./src/components/ChangeLanguage.vue')['default']
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
LanguageIcon: typeof import('./src/components/LanguageIcon.vue')['default']
LanguageSelect: typeof import('./src/components/LanguageSelect.vue')['default']
LineChart: typeof import('./src/components/echarts/LineChart.vue')['default']
ListOrder: typeof import('./src/components/ListOrder.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@ant-design/icons-vue": "^7.0.1",
"ant-design-vue": "^4.2.3",
"axios": "^1.7.4",
"dayjs": "^1.11.13",
"echarts": "^5.5.1",
"gsap": "^3.12.5",
"js-cookie": "^3.0.5",
Expand Down
11 changes: 7 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 31 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,38 @@
<script setup lang="ts">
// import HelloWorld from './components/HelloWorld.vue'
import enUS from "ant-design-vue/es/locale/en_US";
import zhCN from "ant-design-vue/es/locale/zh_CN";
import { ConfigProvider, FloatButton, FloatButtonGroup } from "ant-design-vue";
import {
MoreOutlined,
MessageOutlined,
MailOutlined,
} from "@ant-design/icons-vue";
import { useGlobalStore } from "./stores/global";
import { storeToRefs } from "pinia";
const global = useGlobalStore();
const { language } = storeToRefs(global);
</script>

<template>
<RouterView />
<ConfigProvider :locale="language === 'en' ? enUS : zhCN">
<RouterView />
<FloatButtonGroup trigger="hover" type="primary">
<template #icon>
<MoreOutlined />
</template>
<FloatButton tooltip="Message">
<template #icon>
<MessageOutlined />
</template>
</FloatButton>
<FloatButton tooltip="Mail">
<template #icon>
<MailOutlined />
</template>
</FloatButton>
</FloatButtonGroup>
</ConfigProvider>
</template>

<style scoped>
Expand Down
61 changes: 61 additions & 0 deletions src/components/LanguageSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<script setup lang="ts">
import { h, ref, watchEffect } from "vue";
import { useI18n } from "vue-i18n";
import { setI18NLanguage } from "@/i18n";
import { useGlobalStore } from "@/stores/global";
import { storeToRefs } from "pinia";
import enUS from "ant-design-vue/es/locale/en_US";
import zhCN from "ant-design-vue/es/locale/zh_CN";
import dayjs from "dayjs";
import { Avatar, Dropdown, Menu, MenuProps } from "ant-design-vue";
import { TranslationOutlined } from "@ant-design/icons-vue";
import { MenuInfo } from "ant-design-vue/es/menu/src/interface";
const global = useGlobalStore();
const { language } = storeToRefs(global);
const { locale } = useI18n();
language.value = locale.value;
watchEffect(() => {
dayjs.locale(language.value === "en" ? enUS.locale : zhCN.locale);
});
const items = ref<MenuProps["items"]>([
{
key: "en",
icon: () => h(TranslationOutlined),
label: "English",
title: "English",
},
{
key: "zh-CN",
icon: () => h(TranslationOutlined),
label: "中文",
title: "中文",
},
]);
function handleOperate({ key }: MenuInfo) {
language.value = key as string;
setI18NLanguage(key as string);
}
</script>

<template>
<Dropdown>
<div>
<Avatar>
<template #icon>
<TranslationOutlined />
</template>
</Avatar>
</div>
<template #overlay>
<Menu :items="items" @click="handleOperate" />
</template>
</Dropdown>
</template>

<style scoped lang="scss"></style>
6 changes: 3 additions & 3 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { nextTick } from "vue";
import { createI18n, DefineDateTimeFormat, DefineNumberFormat, type I18nOptions } from "vue-i18n";
import enMessage from "./locales/en";
import zhMessage from "./locales/zh-CN";
import { nextTick } from "vue";

const locale = navigator.language

Expand Down Expand Up @@ -91,11 +91,11 @@ const options: I18nOptions= {

const i18n = createI18n<false, typeof options>(options)

export function setI18NLanguage(i18n: any, locale: string) {
export function setI18NLanguage(locale: string) {
i18n.global.locale.value = locale
}

export async function loadLocaleMessage(i18n: any, locale: string) {
export async function loadLocaleMessage(locale: string) {
const messages = await import(
`./locales/${locale}.ts`
)
Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const enMessage = {
signIn: 'Sign In',
dashboard: 'Dashboard',
operate: {
edit: 'Edit',
Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/zh-CN.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const zhMessage = {
signIn: '登录',
dashboard: '主页',
operate: {
edit: '编辑',
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { createPinia } from 'pinia'
import 'ant-design-vue/dist/reset.css'
import './styles/main.css'

import 'dayjs/locale/zh-cn';

import i18n from './i18n'
import "./permission";

Expand Down
153 changes: 83 additions & 70 deletions src/pages/book/vue.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
<script setup lang="ts">
import { computed, reactive, ref, UnwrapRef } from "vue";
import { SmileOutlined, SearchOutlined } from "@ant-design/icons-vue";
import {
SmileOutlined,
HomeOutlined,
TableOutlined,
} from "@ant-design/icons-vue";
import {
Button,
Breadcrumb,
BreadcrumbItem,
Input,
Radio,
RadioGroup,
Expand All @@ -24,11 +31,6 @@ const current = ref(1);
const pageSize = ref(20);
const total = ref(42);
const editableData: UnwrapRef<Record<string, TableDataItem>> = reactive({});
const searchInput = ref();
const searchState = reactive({
searchText: "",
searchedColumn: "",
});
tableData.value = userList;
Expand Down Expand Up @@ -89,76 +91,87 @@ const handleCancel = (key: string) => {
</script>

<template>
<Table
bordered
:loading="loading"
:row-key="(record) => record.uuid"
:row-selection="rowSelection"
:columns="tableColumns"
:data-source="tableData"
:pagination="pagination"
:scroll="{ y: 400 }"
@change="handleTableChange"
>
<template #title>Header</template>
<template #footer>Footer</template>
<template #headerCell="{ column }">
<template v-if="column.key === 'name'">
<Space> <SmileOutlined />{{ column.title }} </Space>
<div>
<Breadcrumb>
<BreadcrumbItem>
<HomeOutlined />
</BreadcrumbItem>
<BreadcrumbItem>
<TableOutlined />
<span>Vue</span>
</BreadcrumbItem>
</Breadcrumb>
<Table
bordered
:loading="loading"
:row-key="(record) => record.uuid"
:row-selection="rowSelection"
:columns="tableColumns"
:data-source="tableData"
:pagination="pagination"
:scroll="{ y: 400 }"
@change="handleTableChange"
>
<template #title>Header</template>
<template #footer>Footer</template>
<template #headerCell="{ column }">
<template v-if="column.key === 'name'">
<Space> <SmileOutlined />{{ column.title }} </Space>
</template>
</template>
</template>
<template #bodyCell="{ column, text, record }">
<template
v-if="
column.dataIndex === 'name' ||
column.dataIndex === 'age' ||
column.dataIndex === 'address' ||
column.dataIndex === 'email'
"
>
<div>
<Input
<template #bodyCell="{ column, text, record }">
<template
v-if="
column.dataIndex === 'name' ||
column.dataIndex === 'age' ||
column.dataIndex === 'address' ||
column.dataIndex === 'email'
"
>
<div>
<Input
v-if="editableData[record.uuid]"
v-model:value="editableData[record.uuid][column.dataIndex]"
/>
<span v-else>{{ text }}</span>
</div>
</template>
<template v-if="column.dataIndex === 'gender'">
<RadioGroup
v-if="editableData[record.uuid]"
v-model:value="editableData[record.uuid][column.dataIndex]"
/>
<span v-else>{{ text }}</span>
</div>
</template>
<template v-if="column.dataIndex === 'gender'">
<RadioGroup
v-if="editableData[record.uuid]"
v-model:value="editableData[record.uuid][column.dataIndex]"
>
<Radio
v-for="item in column.filters"
:key="item.value as string"
:value="item.value"
>
{{ item.text }}
</Radio>
</RadioGroup>
<span v-else>{{ text }}</span>
</template>
<template v-if="column.key === 'action'">
<div>
<Space v-if="editableData[record.uuid]">
<TypographyLink @click="handleSava(record.uuid)"
>Save</TypographyLink
<Radio
v-for="item in column.filters"
:key="item.value as string"
:value="item.value"
>
<Popconfirm
title="Sure to cancel?"
@confirm="handleCancel(record.uuid)"
>
<TypographyLink>Cancel</TypographyLink>
</Popconfirm>
</Space>
<Button v-else type="primary" @click="handleEdit(record.uuid)">
Edit
</Button>
</div>
{{ item.text }}
</Radio>
</RadioGroup>
<span v-else>{{ text }}</span>
</template>
<template v-if="column.key === 'action'">
<div>
<Space v-if="editableData[record.uuid]">
<TypographyLink @click="handleSava(record.uuid)"
>Save</TypographyLink
>
<Popconfirm
title="Sure to cancel?"
@confirm="handleCancel(record.uuid)"
>
<TypographyLink>Cancel</TypographyLink>
</Popconfirm>
</Space>
<Button v-else type="primary" @click="handleEdit(record.uuid)">
Edit
</Button>
</div>
</template>
</template>
</template>
</Table>
</Table>
</div>
</template>

<style scoped lang="scss"></style>
Loading

0 comments on commit 52e3cbf

Please sign in to comment.