Skip to content

Vue3中封装$k

如果你用的是 vite 搭建的项目,你可以写成一个自动导入的函数。并且如果你用的是 vue 的话,就更方便了

根目录新建一个文件夹及文件,比如preFunc/index.ts

这里的 i18n 是 vue-i18n,也就是使用的createI18n 创建出来的

ts
// src/locales/i18n.ts
import { createI18n, type I18n } from 'vue-i18n';
import cn from './cn.json';
import en from './en.json';

// 默认语言
export const defaultLang: string = 'en';

const langArr: string[] = ['en', 'cn'];

let i18n: I18n;
let lang: string = localStorage.getItem('lang') || '';

const existInx: number = langArr.findIndex((item: string): boolean => item === lang);
if (existInx === -1) {
  localStorage.removeItem('lang');
} else {
  document.body.className = 'lang-' + lang;
}

i18n = createI18n({
  fallbackLocale: defaultLang,
  globalInjection: true,
  legacy: false, // you must specify 'legacy: false' option
  locale: localStorage.getItem('lang') || defaultLang,
  messages: {
    cn,
    en,
  },
});

export default i18n;
ts
// preFunc/index.ts
import i18n from '@/locales/i18n';

export const $k = (strings: TemplateStringsArray | string, ...values: any[]) => {
  // 处理普通函数调用
  if (typeof strings === 'string') {
    return strings;
  }

  const firstPart = strings[0];

  if (firstPart.includes('__')) {
    const [key, firstStaticText] = firstPart.split('__');

    const result = (i18n.global as any).t(key, [...values]);
    if (result) {
      return result;
    }

    // 兜底处理
    const newStrings = [...strings];
    newStrings[0] = firstStaticText;

    return newStrings.reduce((result, str, i) => {
      const value = values[i] !== undefined ? values[i] : '';
      return result + str + value;
    }, '');
  }

  // 普通拼接
  return strings.reduce((result, str, i) => {
    const value = values[i] !== undefined ? values[i] : '';
    return result + str + value;
  }, '');
};

然后在 vite.config.ts 中配置

ts
import AutoImport from 'unplugin-auto-import/vite';
export default () => {
  return defineConfig({
    plugins: [
      AutoImport({
        imports: ['vue', 'vue-router'], // 自动导入vue和vue-router相关函数
        include: [/\.[tj]sx?$/, /\.vue$/, /\.vue\?vue/],
        dts: 'src/auto-import.d.ts', // 生成 auto-import.d.ts 全局声明
        resolvers: [ElementPlusResolver()],
        dirs: ['./preFunc/**'],
      }),
    ],
  });
};

为了防止ts报警告,可以在全局的d.ts中声明

ts
interface ComponentCustomProperties {
  $k: (strings: TemplateStringsArray | string, ...values: any[]) => string;
}

为了能在template中使用,需要在main.ts中加入

ts
const vueApp = createApp(App);
// 多语言翻译标记
vueApp.config.globalProperties.$k = (
  strings: TemplateStringsArray | string,
  ...values: any[]
): string => $k(strings, ...values);