美文网首页
2018-12-29

2018-12-29

作者: 天空之城_2692 | 来源:发表于2018-12-29 19:03 被阅读8次

    H5对接多语言平台

    首先,对接多语言平台我们需要将本地的多语言给到多语言平台,但是多语言平台那边识别不了我们本地文件的格式,我们首先需要将格式转换。类似如下:

    代码块

    menu: {
            'homePage': '首页',
            'message': '消息',
            'me': '我的',
            'work': '工作',
      },
    

    平台需要我们将如上代码转换成类似如下的格式

        "menu.homePage": "首页",
        "menu.message": "消息",
        "menu.me": "我的",
        "menu.work": "工作",
    

    由于考虑到我们需要将组件库的多语言和本项目多语言进行转换然后生成转换后的文件,我这里我们可以通过如下js代码进行操作

    function getLanguage(obj, map, preKey) {
        preKey = preKey || '';
        for (var key in obj) {
            let temp = preKey ? preKey + '.' + key : key;
            if (typeof obj[key] === 'string') {
                map[temp] = obj[key];
            } else {
                getLanguage(obj[key], map, temp);
            }
        }
        return map;
    }
    

    如上是将对象转换的逻辑,紧接着需要将生成的文件写入文件

    let convertPath = path.resolve(__dirname, './i18n/all-zh-CN.json');
    var convertFile = getLanguage(_.merge(require('./i18n/walle-zh-CN.js'), require('./i18n/zh-CN.js')), convertMap);
    

    这里我暂时将文件写入文件i8n下面名为all-zh-CN.json的文件中,convertFile是组件库文件和本地的文件,经getLanguage函数转化后数据。接下来就是要把此文件写入。起初文件写入成功,但并不是我想要的文件格式,尝试很多写法,文件内容总显示[object objec]或者显示因文件过大等等的文字很郁闷。

    path.resolve(_dirname,filename) __dirname变量
    在任何模块文件内部,可以使用__dirname变量获取当前模块文件所在目录的完整绝对路径
    最初的写法(参照别的项目)

    fs.open(convertPath, 'w+', function(e){
        if(e) throw e;
        fs.writeFile(convertPath, md, function(e){
            if(e) throw e;
            console.log('转换成功');
        })
    })
    

    查fs用法如下

    node 操作文件流 fs
    在node中通过fs模块来和系统中的文件进行交互
    通过fs模块可以对磁盘中的文件做各种增删改查的操作

    1、同步写入

    1.打开要写入的文件
    fs.openSync(path, flags[, mode])
    该方法用来打开一个文件
    参数:
    path:路径,要打开文件的路径
    flags:操作的类型,要对文件做什么操作
    需要字符串作为参数
    "w" 写
    "r" 读
    "a" 追加
    mode:可选参数,一般不传,用来设置文件的权限
    返回值:
    fd 文件的描述符
    2.写入并保存
    fs.writeSync(fd, string[, position[, encoding]])
    该方法用于向文件中写入内容
    参数:
    fd: 文件的描述符,需要指定要写入文件的描述符
    string: 要写入的内容
    position: 开始写入的位置
    encoding: 写入内容的字符编码,默认utf-8
    3.关闭文件
    fs.closeSync(fd):: 该方法用来关闭文件
    参数:
    fd 文件的描述符
    实例
    //引入fs模块
    var fs=require('fs');
    var fd=fs.openSync('gzl.txt','w');
    fs.writeSync(fd,'1111',10,'utf-8');
    fs.closeSync(fd);

    3.异步写入

    1.打开文件
    fs.open(path, flags[, mode], callback)
    参数:callback
    回调函数,会在文件打开以后执行
    回调函数中会有两个参数:
    err: 错误信息,如果操作过程中出现了错误,则该对象存在,如果没有出现错误,则该参数的值为null
    错误优先
    fd: 文件的描述符

    2.写入文件
    fs.write(fd, string[, position[, encoding]], callback)
    callback 回调函数会在写入完毕以后执行
    参数:
    err 错误对象
    byte 写入的字节数
    data 写入的数据

    3.关闭文件
    fs.close(fd, callback)
    按照上述描述尝试修改并没有解决我的问题,然后自己瞎看项目时忽然就想着把写入的文件用JSON.stringify做下转换真的好了!!写入的文件没有换行符,看起来一团乱,格式化文件就好了。
    接着就是获取平台的多语言数据了,在template.esj文件中写入如下代码

    <script>
            window.LanguageData = {};
            var xhr = new XMLHttpRequest();
            xhr.open("GET",'/api/common/language',false);
            xhr.send();
            if (xhr.status == 200){
                var result = xhr.response;
                result = JSON.parse(result);
                window.LanguageData = result.data;
            }
        </script>
    

    在项目的i8n项目中写入如下代码:

    let language = 'zh-CN' || globalConfig.language;
    
    i18next.init({
        debug: true,
        lng: language,
        returnObjects: true,//
        keySeparator: '@',//很重要
        resources: {
            [language]: {
                translation: window.LanguageData || {}
            }
        }
    });
    

    起初多语言总是转换不成功,发送a:{b:1}这种格式的文件是没问题的,但是换成a.b=1的就是不可以,这就是上面需要配置的那个很重要的属性。keySeparator 属性不配置默认为., i18next的查找文件默认先查a对象,然后再找其下面的属性,这个keySeparator就是个标识符默认按照此分隔符查找其前面的对象再找到对应的属性。也就是说它识别不了a.b只能是a{b:1}来查找。keySeparator默认是.我们可以配置除.以外的任意字符。
    到此我们的界面也就修改成功了。

    相关文章

      网友评论

          本文标题:2018-12-29

          本文链接:https://www.haomeiwen.com/subject/ecvplqtx.html