国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

編寫簡單i18n庫

DevWiki / 1950人閱讀

摘要:因?yàn)閮纱蔚拈_發(fā)維護(hù)體驗(yàn)產(chǎn)生了對比,使我產(chǎn)生了不小的興趣假設(shè)一個簡單的頁面需要多語言。兩個簡單的區(qū)別就是和替換的區(qū)別。樣式模式其實(shí)就是簡單的切換。當(dāng)修改的某個值時,會觸發(fā)對應(yīng)的,并發(fā)射信號通知節(jié)點(diǎn)去更新。

i18n是什么?i18n(其來源是英文單詞internationalization的首末字符i和n,18為中間的字符數(shù))是“國際化”的簡稱。

前言

第一次接觸多語言是用野生javascript寫H5應(yīng)用的時候,那時候?qū)懥艘淮蠖训睦圪樦貜?fù)的代碼用來切換頁面的多語言,之后自然發(fā)現(xiàn)很難維護(hù)啦。至于到第二次開發(fā)另一個H5應(yīng)用的時候,用了vue做了一個SPA。多語言自然用了官方的vue-i18n。

因?yàn)閮纱蔚拈_發(fā)維護(hù)體驗(yàn)產(chǎn)生了對比,使我產(chǎn)生了不小的興趣:假設(shè)一個簡單的頁面需要多語言。當(dāng)然用不著vue,但是也不想用jquery怎么辦?如果要開發(fā)類似的i18n庫,我該如何實(shí)現(xiàn)?

于是花了三天(應(yīng)該也是兩個月前了)寫了這個工具庫n-i18n,以后寫多語言頁面的工作量就可以減少啦~

分析

簡單分析后,發(fā)現(xiàn)可以參考vue-i18n的配置。但是由于沒有實(shí)現(xiàn)也沒有必要實(shí)現(xiàn)模板引擎。因此其實(shí)可以將配置參數(shù)放在DOM節(jié)點(diǎn)的dataset(data-i18n)屬性上。遍歷讀取有該dataset的節(jié)點(diǎn)。解析里面配置的參數(shù)后,就可以讀取該節(jié)點(diǎn)應(yīng)該綁定多語言里的哪個文本,配置什么參數(shù)和數(shù)據(jù)。

在實(shí)際開發(fā)中。多語言有時候往往不止切換單純的文本。有時候可能是切換HTML,甚至切換圖片,樣式(比如background-image)的情況出現(xiàn)。因此渲染模式也被我分為了$t; $h; $m; $c四種模式,分別對應(yīng)文本模式、HTML模式、圖片模式、樣式模式。

實(shí)現(xiàn)難點(diǎn)或者說有趣的點(diǎn)在于:

如何準(zhǔn)確尋找到有指定dataset的所有DOM節(jié)點(diǎn)?

巧妙利用正則解析dataset中的多樣配置。

多種模式如何準(zhǔn)確渲染和組合渲染?

實(shí)現(xiàn)依賴動態(tài)數(shù)據(jù),數(shù)據(jù)改變便更新對應(yīng)的DOM節(jié)點(diǎn)。

基礎(chǔ)實(shí)現(xiàn)

代碼參考:https://github.com/Gotjoy/n-i18n/blob/master/src/i18n-a.js

1. 如何準(zhǔn)確尋找到有指定dataset的所有DOM節(jié)點(diǎn)?

利用遞歸一層層遍歷節(jié)點(diǎn)樹,符合要求的節(jié)點(diǎn)就保存在一個map里,留待之后對其的操作的索引。這里的name其實(shí)是默認(rèn)的i18n這個字符串,當(dāng)然也可以配置其他字符串,然后就可以在節(jié)點(diǎn)中配置屬性如data-i18n=""

(function _trace(parent) {
  const children = parent.children;
  for (let i = 0, len = children.length; i < len; i++) {
    const child = children[i];
    if (child.dataset[name]) {
      map[`${name}#${++tid}`] = child;
    }
    if (child.children.length > 0) {
      _trace(child);
    }
  }
}(this.$mount));
2. 巧妙利用正則解析dataset中的多樣配置

首先利用字符串截取操作的api來解析配置雖然也可以,但是會相當(dāng)啰嗦,翻看許多優(yōu)秀框架的源碼,都是一般傾向于用正則去解析。比如說我會存在以下四種配置,那么該如何去解析data-i18n里面的配置文本從而拿到自己感興趣的信息呢?

在這里有兩個及其重要的正則,代碼稍后亮相。

baseRe正則負(fù)責(zé)匹配如上的"message.hello"($1)和{msg: "偉大的渺小~", msg2: "Until the day!"}($2)
confRe正則負(fù)責(zé)進(jìn)一步匹配{msg: "偉大的渺小~", msg2: "Until the day!"}文本中key($1)和value($2)

正則的試驗(yàn)推薦這個網(wǎng)站,多去嘗試https://regexr.com。當(dāng)然正則我不會詳細(xì)介紹了,畢竟也是一個很深厚的學(xué)問。

經(jīng)過正則的處理,已經(jīng)拿到了全部感興趣的信息。接下來就是可以利用這些信息去讀取多語言配置里lang的數(shù)據(jù)并且更新DOM節(jié)點(diǎn)了。

const baseRe = /$[t|h|c|m]([""](.*?)[""],*s*(.*))/g;
const confRe = /(w+):s*[""](.+?)[""]/g;
let base = "";
let conf = Object.create(null);

c.replace(baseRe, (match, $1, $2) => {
  base = $1;
  if ($2) {
    $2.replace(confRe, (match, $1, $2) => {
      conf[$1] = $2;
    });
  }
});
const lang = {
  en: {
    message: {
      hello: "hello world! {msg2}"
    }
  },
  zh: {
    message: {
      hello: "你好,世界! {msg}"
    }
  }
};

細(xì)心的同學(xué)可能會發(fā)現(xiàn)一個問題了,如何以a.b.c形式獲取對象屬性這個不難。一個遍歷即可,簡單實(shí)現(xiàn)的話只有value不是原始值就繼續(xù)往里面走就可以了。

function getValueBy (obj, keystr) {
    const keyset = keystr.split(".");
    for (let i = 0, len = keyset.length; i < len; i++) {
        let v = obj[keyset[i]];
        if (v || _.isPrimitive(v)) {
            obj = v;
        }
    }
    return _.isPrimitive(obj) ? obj : "";
}

找到數(shù)據(jù)了后,配置文本lang中占位的{msg}的替換利用動態(tài)生成正則new RegExp("{" + keys[i] + "}", "g");全局替換即可。

3. 圖片模式和樣式模式

以上講的是文本模式和HTML模式。兩個簡單的區(qū)別就是innerTextinnerHTML替換的區(qū)別。但是圖片模式和樣式模式怎么實(shí)現(xiàn)?

首先容我啰嗦幾句,為什么我會創(chuàng)造出這兩種模式呢?因?yàn)橛袝r候設(shè)計稿中的某些圖片的特殊文本也是多語言的,藝術(shù)字體(什么高光,花式漸變、浮雕等等)不可能用代碼實(shí)現(xiàn),這時候每個多語言對應(yīng)切個圖片就好了,然后利用圖片模式切換就好了。樣式模式也是差不多的應(yīng)用場景了。

圖片模式簡單實(shí)現(xiàn)方法就是路徑的替換(當(dāng)然前提是一定要對多語言圖片命名和存放位置都進(jìn)行強(qiáng)約束)。樣式模式其實(shí)就是簡單的切換class。

// class渲染
function render$c (v, c) {
    const locale = this.$locale;
    const langs = Object.keys(this.$messages);
    for (let i = 0, len = langs.length; i < len; i++) {
        if (langs[i] !== locale) {
            _.removeClass(v, `${langs[i]}-${c.base}`);
        }
    }
    _.addClass(v, `${locale}-${c.base}`)
}

// 圖片渲染
function render$m (v, c) {
    const locale = this.$locale;
    const langs = Object.keys(this.$messages).join("|");
    const nameRe = new RegExp("(/(" + langs + "))?/[^/]+(?=.[^/]*$)", "g");
    const src = v.getAttribute("src");
    const path = src.replace(nameRe, `/${locale}/${c.base}`);
    
    v.setAttribute("src", path);
}
4. 多種模式如何準(zhǔn)確渲染

多種模式混合使用的時候,如何區(qū)分并準(zhǔn)確渲染?這個只需要合理斷開配置文本,并分別運(yùn)用在該節(jié)點(diǎn)上即可。需要注意的是,斷開配置時應(yīng)當(dāng)判斷分號是否不在文本里,否則容易誤傷友軍。

先占位后替換加載新圖片
const dataI18n = v.dataset[name].split(/;(?:s*$[t|h|c|m])/g);
dataI18n.forEach(c => {
  const _c = this.parse(c.trim());
  if (c.includes("$t")) {
    this.render$t(v, _c);
  }
  if (c.includes("$h")) {
    this.render$h(v, _c);
  }
  if (c.includes("$c")) {
    this.render$c(v, _c);
  }
  if (c.includes("$m")) {
    this.render$m(v, _c);
  }
});
更進(jìn)一步

考慮應(yīng)用場景如下,某些多語言數(shù)據(jù)依賴于后端返回,并在應(yīng)用生命周期內(nèi)持續(xù)更新。為了避免低效的手動操作,這些多語言數(shù)據(jù)應(yīng)該動態(tài)依賴,實(shí)現(xiàn)數(shù)據(jù)改變的時候動態(tài)更新依賴了這些數(shù)據(jù)的DOM節(jié)點(diǎn)就好了。

如何做到這一點(diǎn)。利用Object.defineProperty這個因vue而讓大家熟悉的api,遍歷配置的中data并進(jìn)行觀察。重點(diǎn)是在里面的setter。當(dāng)修改data的某個值時,會觸發(fā)對應(yīng)的setter,并發(fā)射信號通知DOM節(jié)點(diǎn)去更新。

代碼參考:https://github.com/Gotjoy/n-i18n/blob/master/src/i18n-b.js

總結(jié)

造輪子是個學(xué)習(xí)探索的過程,希望大家可以喜歡這篇文章。當(dāng)然還有如果n-i18n這個工具對你們有所啟發(fā)或者幫助,那就更好了~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/51842.html

相關(guān)文章

  • 編寫簡單i18n

    摘要:因?yàn)閮纱蔚拈_發(fā)維護(hù)體驗(yàn)產(chǎn)生了對比,使我產(chǎn)生了不小的興趣假設(shè)一個簡單的頁面需要多語言。兩個簡單的區(qū)別就是和替換的區(qū)別。樣式模式其實(shí)就是簡單的切換。當(dāng)修改的某個值時,會觸發(fā)對應(yīng)的,并發(fā)射信號通知節(jié)點(diǎn)去更新。 i18n是什么?i18n(其來源是英文單詞internationalization的首末字符i和n,18為中間的字符數(shù))是國際化的簡稱。 前言 第一次接觸多語言是用野生javascri...

    txgcwm 評論0 收藏0
  • React項(xiàng)目國際化(antd)多語言開發(fā)

    摘要:本國際化方案僅針對技術(shù)棧,且不會涉及服務(wù)端國際化內(nèi)容。引入多語言環(huán)境的數(shù)據(jù)雖然我只用到了文本翻譯的功能,以為就不需要加載這些數(shù)據(jù),但后來發(fā)現(xiàn)這是必須的步驟。 前言 最近新接了一個項(xiàng)目,從0開始做,需要做多語言的國際化,今天搞了一下,基本達(dá)到了想要的效果, 在這里簡單分享下: showImg(https://segmentfault.com/img/bVbuiJB); 背景國際化方案國際...

    tracymac7 評論0 收藏0
  • React項(xiàng)目國際化(antd)多語言開發(fā)

    摘要:本國際化方案僅針對技術(shù)棧,且不會涉及服務(wù)端國際化內(nèi)容。引入多語言環(huán)境的數(shù)據(jù)雖然我只用到了文本翻譯的功能,以為就不需要加載這些數(shù)據(jù),但后來發(fā)現(xiàn)這是必須的步驟。 前言 最近新接了一個項(xiàng)目,從0開始做,需要做多語言的國際化,今天搞了一下,基本達(dá)到了想要的效果, 在這里簡單分享下: showImg(https://segmentfault.com/img/bVbuiJB); 背景國際化方案國際...

    wushuiyong 評論0 收藏0
  • i18n-json-compiler 一個為TypeScript編寫的國際化方案

    摘要:在寫一個的過程中難免會遇到要做國際化的時候也就是需要根據(jù)不同的地區(qū)展示不同的文案對于簡單的文本直接用一個或者或者一個變量就能搞定但是有時候需要在一句話中加入變量就比較麻煩或者說比較惡心了比如這樣的情況有個人喜歡了你應(yīng)運(yùn)而生其作用是將模板 在寫一個APP的過程中, 難免會遇到要做國際化的時候. 也就是需要根據(jù)不同的地區(qū), 展示不同的文案. 對于簡單的文本, 直接用一個xml或者json或...

    Zack 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<