简介
本文介绍了如何利用Vue作为前端框架,NestJS作为后端框架,实现数据国际化,并采用分库分表的方式进行数据存储。
技术栈
- Vue.js
- NestJS
- 数据库(示例使用MySQL)
- i18n(国际化)
项目结构
前端(Vue)
lua
plaintextCopy code
my-vue-app/
|-- src/
| |-- assets/
| |-- components/
| |-- i18n/
| |-- views/
| |-- App.vue
| |-- main.js
|-- public/
|-- package.json
|-- ...
后端(NestJS)
lua
plaintextCopy code
my-nest-app/
|-- src/
| |-- modules/
| |-- controllers/
| |-- services/
| |-- main.ts
|-- package.json
|-- ...
数据库设计
采用分库分表的方式,存储多语言数据。
后端实现
安装依赖
bash
cd my-nest-app
npm install --save @nestjs/typeorm typeorm mysql2
配置TypeORM
在my-nest-app/src/app.module.ts
中配置数据库连接。
JavaScript
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
name: 'demo1',
type: 'mysql',
host: 'localhost',
port: 3306, // default port for postgres
username: 'root',
password: 'root',
database: 'demo1',
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: true,
}),
TypeOrmModule.forRoot({
name: 'demo2',
type: 'mysql',
host: 'localhost',
port: 3306, // default port for postgres
username: 'root',
password: 'root',
database: 'demo2',
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: true,
}),
],
})
export class DatabaseModule {}
实现服务
使用nest g res user
来创建user模块
javascript
nest g res user
现在我们在user.entity.ts里面定义数据库实体
javascript
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
启动服务看到数据库里面表是否被创建:
数据库创建成功,现在我们要根据前端请求参数来访问对应的数据库。
我们使用postman请求路由,并设置请求头:
我们现在创建一个守卫来获取到请求头里面的语言设置:
javascript
nest g gu internationalization
在internationalization.guard.ts里面设置:
javascript
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class InternationalizationGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
// 获取请求头
const request = context.switchToHttp().getRequest();
const header = request.headers;
// 获取语言
request.lang = header.lang;
return true;
}
}
现在我们到user里面的user.controller.ts里面去设置:
导入并设置:
javascript
import { InjectConnection } from '@nestjs/typeorm';
import { Connection } from 'typeorm';
constructor(
private readonly userService: UserService,
@InjectConnection('demo1') private conn1: Connection,
@InjectConnection('demo2') private conn2: Connection,
) {}
现在我们到请求的接口里面去设置:
javascript
@Get(':id')
async findOne(@Param('id') id: string, @UserInfo() userInfo: any) {
let connection: Connection;
if (userInfo === 'zh') {
connection = this.conn1;
} else if (userInfo === 'en') {
connection = this.conn2;
} else {
throw new Error('Invalid db parameter');
}
// return this.userService.findOne(+id);
const result = await connection.getRepository(User).find({
where: { id: +id },
});
return result;
}
这里我就不进行封装了,需要使用的自行封装一下。 我们使用postman测试一下:
请求没有问题,后端就已经完成了,我们在去main.ts里面设置一下跨域就好了。
前端实现
安装依赖
lua
vue create my-vue-app
cd my-vue-app
npm install --save vue-i18n axios element-plus
配置国际化
在my-vue-app/src/utils/i18n.js
中配置国际化。
JavaScript
import { createI18n } from "vue-i18n";
const messages = {
en: require("./../locales/en.json"),
zh: require("./../locales/zh.json"),
};
const i18n = createI18n({
locale: "en", // 默认语言
messages,
});
export default i18n;
现在去创建locales/en.json:
javascript
{
"message": {
"greeting": "Hello!"
}
}
现在去创建locales/zh.json:
javascript
{
"message": {
"greeting": "你好!"
}
}
在main.js里面导入i18n.js
javascript
import { createApp } from "vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import App from "./App.vue";
import i18n from "./utils/i18n";
createApp(App).use(i18n).use(ElementPlus).mount("#app");
实现组件
在app.vue里面使用:
html
<template>
<div>
<p>{{ $t("message.greeting") }}</p>
<el-button type="primary" @click="changeLanguage('zh')">切换中文</el-button>
<el-button type="success" @click="changeLanguage('en')">切换英文</el-button>
</div>
</template>
现在实现语言切换
javascript
changeLanguage(lang) {
localStorage.setItem("lang", lang);
this.$i18n.locale = lang;
},
现在按钮就可以实现语言切换了
前后端联调
在src目录下面新建api目录像这样
现在我们来配置axios请求:
现在我们来配置请求路径以及请求头:
javascript
import axios from "axios";
const api = axios.create({
baseURL: "http://localhost:3000",
});
// 请求拦截器
api.interceptors.request.use(
(config) => {
const lang = localStorage.getItem("lang") || "zh";
config.headers["lang"] = lang;
// 在请求发送之前做一些处理
return config;
},
(error) => {
// 当请求异常时做一些处理
return Promise.reject(error);
}
);
export default api;
在app.vue里面导入:
javascript
import api from "./api/index.js";
并创建请求函数:
javascript
data() {
return {
name: "",
};
},
getUserInfo() {
api.get("/user/1").then((res) => {
console.log(res.data[0].name);
this.name = res.data[0].name;
});
并且在切换语言的时候保存到localStorage里面,
javascript
mounted() {
this.getUserInfo();
},
methods: {
changeLanguage(lang) {
localStorage.setItem("lang", lang);
this.$i18n.locale = lang;
this.getUserInfo();
},
现在打开界面:
现在,你已经配置好了Vue + NestJS的数据国际化分库分表项目。请根据实际需求和业务逻辑进行更详细的实现和优化。