Vue+Nestjs分库分表实现数据国际化

简介

本文介绍了如何利用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的数据国际化分库分表项目。请根据实际需求和业务逻辑进行更详细的实现和优化。

相关推荐
小宋10214 分钟前
el-table的select回显问题
javascript·vue.js·elementui
Bee.Bee.1 小时前
vue3提供的hook和通常的函数有什么区别
前端·javascript·vue.js
Nano1 小时前
Vue响应式系统的进化:从Vue2到Vue3.X的深度解析
前端·vue.js
某人的小眼睛1 小时前
vue3 element-plus 大文件切片上传
前端·vue.js
来自星星的猫教授1 小时前
Vue 3.6前瞻:响应式性能革命与Vapor模式展望
前端·javascript·vue.js
用户3802258598242 小时前
Vue3源码解析:深度解读ref实现源码
vue.js
Chuck1sn2 小时前
我把 Cursor AI 整合到 Ruoyi 中,从此让 Java 脚手架脱离人工!
java·vue.js·后端
一只叫煤球的猫2 小时前
1200行代码的前端组件?这套拆分套路让代码从此优雅
前端·vue.js·性能优化
武昌库里写JAVA3 小时前
IDE(集成开发环境),集成阿里云的通义大模型
vue.js·spring boot·毕业设计·layui·课程设计
前端大卫3 小时前
localStorage 也能监听变化?带你实现组件和标签页的同步更新!【附完整 Vue/React Hook 源码】
前端·vue.js·react.js