如何使用vite动态导入json文件

Den*_*han 8 nuxt.js vue-i18n vite

我在Nuxtjs项目中使用vue-i18n,我想用 vite 动态导入我的语言环境文件。

当我使用 webpack 时,这些代码运行良好

插件/i18n.js

import Vue from 'vue';
import VueI18n from 'vue-i18n';
import config from '@/config';

Vue.use(VueI18n);

let messages = Object;

config.locale.available.forEach(locale => {
    messages[locale] = require(`~/locales/${locale}.json`);
});

export default ({ app, store }) => {
    app.i18n = new VueI18n({
        locale: store.state.locale.locale,
        messages: messages
    });
}
Run Code Online (Sandbox Code Playgroud)

require()我发现vitejs中没有,还有vitejs的glob-import功能

  1. 所以我首先尝试如下:
let messages = Object,
    languages = import.meta.glob('../locales/*.json'); // => languages = {} (languages only get {} value)

config.locale.available.forEach(locale => {
    messages[locale] = languages[`../locales/${locale}.json`];
});
Run Code Online (Sandbox Code Playgroud)

languages唯一有价值{}的。

  1. 然后我尝试使用import()
let messages = Object,
    translate = lang => () => import(`@/locales/${lang}.json`).then(i => i.default || i);

config.locale.available.forEach(locale => {
    messages[locale] = translate(locale);
});
Run Code Online (Sandbox Code Playgroud)

终端和控制台都没有错误,但没有正确加载区域设置文件。


只要我import()一一解答,问题就会消失:

import en from '@/locales/en.json';
import fr from '@/locales/fr.json';
import ja from '@/locales/ja.json';

let messages = Object;

messages['en'] = en;
messages['fr'] = fr;
messages['ja'] = ja;
Run Code Online (Sandbox Code Playgroud)

代码沙盒

但是,如何动态导入呢?

我用谷歌搜索了一下,但帮助不大。非常感谢任何人的帮助!

小智 5

所以,我想我根据@LiuQixuan 在 GitHub 上的回答找到了一些答案。

//Importing your data 
const data = import.meta.glob('../locales/*.json')

//Ref helps with promises I think. I'm sure there are more elegant ways.
const imp = ref([{}])

// From https://github.com/vitejs/vite/issues/77
// by LiuQixuan commented on Jun 20

for (const path in data) {
    data[path]().then((mod) => { 
        imp.value.push(mod)
    })
}
Run Code Online (Sandbox Code Playgroud)

从那里,我迭代了imp.values,然后我可以循环调用每个文件,并使用以下方法获取数据:

JSON.parse(JSON.stringify(**Your data**))
Run Code Online (Sandbox Code Playgroud)

我的示例 Vue HTML 是这样的:

    <div v-for="(module,i) in imp" :key="i">
          <div v-for="(data,j) in module" :key="j">

            //at this point you can read it fully with {{ data }}

            <div v-for="(jsonText, k) in JSON.parse(JSON.stringify(data))" :key=k">
              {{ jsonText.text }}
              <div v-for="insideJson in jsonText" :key="insideJson">
                {{ insideJson.yourtext }}
              </div>
            </div>
          </div>
     </div>
Run Code Online (Sandbox Code Playgroud)

这样,我就可以访问文件中的每个对象。我认为您还有其他需求,但这证明您可以访问每个文件而无需独立导入。

我知道这有点粗糙。我使用了 Stringify 解析,因为数据总是像以前一样返回,所以我无法直接访问。我确信有一个更优雅的解决方案,但这就是我想到的。

我最初是尝试动态导入图像,在弄清楚之后,我将该方法应用于您的问题。

对于任何想从文件夹动态导入多图像的人来说,请使用:

new URL(*, import.meta.url)
Run Code Online (Sandbox Code Playgroud)

和以前一样,但添加了:

    for (const path in modules) {
      modules[path]().then(() => {
        //*************
        const imgURL = new URL(path, import.meta.url)
        //*************
        gallery.value.push(imgURL)
      })
    }
    //Then reference that gallery.value in your :src
Run Code Online (Sandbox Code Playgroud)