vue-i 18 nからvueプラグインがどのように動作するかを分析する
10717 ワード
物語の背景
vue-i 18 nはvueコードの貢献量2位のvue core teamの日本人のお兄さんが書いたもので、サードパーティのプラグインですが、使うと気持ちがいいです.githubでvue i 18 nを検索すると、結果は少なくなく、いくつかの粗いものがあり、jqueryのlibを使っても六七十人のstarがあります.(ツッコミを止める).すごい人は明らかにデザインの上でコードの上ですべてとても高いランクでしょう.
今日の物語の主役repoはvue-i 18 nとiViewです.彼らを使用している間にエラーを報告し、issueを表示し、issueでコードを取得し、問題を不明に解決しました.
これは私が
まず結果を述べると、
この文章を読んでどのような点がわかるかを話してみましょう. の上のコードはなぜ を回避したのか. vue-i 18 nの差分式
Vue.use
(冒頭の話に続く)、以前は
まず、
コードの文法解釈は注釈に書かれていますが、プラグインの名前が
まとめ:
また、uiコンポーネントのinstallメソッドの大部分は
統合エラーを回避する原理を分析する
2行目と3行目で2番目のパラメータの操作が行われていることは明らかですが、
わあ、なるほど、
Vue.mixin
では、私たちが伝えた方法は
なるほど、この
同様に、解釈も注釈に書かれていますが、4つのinstallの核心には私のmixinの方法が詳しくありません.次に、
文字通りmerge配置、optionsつまり
$tがどのように動作するか
ロードを行った後、domの補間表現で呼び出すだけで翻訳できます.
以前の章ではいくつかのロード方法について理解していたが、
≪ロード|Load|emdw≫
まずvue-i 18 nがどのようにロードされたかを見てみましょう.
ここで2つに分けます. が実行されている
install
前述したように、installのコアの4つの方法は、
Directiveとcomponentはそれぞれ登録命令と登録コンポーネントであり、ここでは展開せず、
見てみろjsの
なるほど、我々が呼び出す にどのようにロードするかである. _tメソッドは、どこでVueにロードされるかを書く 問題を抱えてmixinを見続けますjs. mixin.jsには2つの方法しかありません.beforeCreateとbeforeDestroyです.私は大体beforeCreateを見て、現在のcomponentのVueを構築する役割を果たしています.i 18 n変数、この変数はVue.$i 18 nのgetterの指向は、なぜgetterを書くのかという理由も出ているが、i 18 n-loaderは単一ファイルにローカル言語パッケージを書くことを許可しているので、mergeしてローカル言語環境を生成する.
ではmixinではどのように初期言語パッケージを取得したのでしょうか.ソース:
Vueインスタンス構築中にロードされたVueI 18 nインスタンス
(ざらざらしてみると)、Vueバーパラメータが判断して自分の
VueI 18 nの構造を見てみましょう.コードは600行ありますが、初期化時に実行されました
vuexもそう書いてあるようですが、tメソッドはこのファイルに書かれていますが、どのようにロードするかはvueソースコードを見なければなりません.次回分解するしかありません.
テキストアドレス
vue-i 18 nはvueコードの貢献量2位のvue core teamの日本人のお兄さんが書いたもので、サードパーティのプラグインですが、使うと気持ちがいいです.githubでvue i 18 nを検索すると、結果は少なくなく、いくつかの粗いものがあり、jqueryのlibを使っても六七十人のstarがあります.(ツッコミを止める).すごい人は明らかにデザインの上でコードの上ですべてとても高いランクでしょう.
今日の物語の主役repoはvue-i 18 nとiViewです.彼らを使用している間にエラーを報告し、issueを表示し、issueでコードを取得し、問題を不明に解決しました.
Vue.use(iView, {
i18n: (key, value) => i18n.vm._t(key, value)
})
これは私が
Vue.use
が2番目のパラメータを伝えることができることを初めて知ったので、何が起こったのか知りたいです.まず結果を述べると、
iView
がvue-i18n
への統合を行ったため、文書をよく見ていないために不適切に使用する問題である.研究期間中にelement uiのコードを見た.iView
の対vue-i18n
の集積は彼らを写したものであることが分かった.(ツッコミを止める).この文章を読んでどのような点がわかるかを話してみましょう.
Vue.use()
何をしましたかiView
とvue-i18n
の統合使用のエラーVue.mixin()
何をしましたか$t
の方法はどこから来たのか(私はこの方法しか使っていないので)次から私たちの物語を始めます.Vue.use
(冒頭の話に続く)、以前は
Vue.use()
を使っていたシーンはVue.use(vuex)
、Vue.use(router)
などであった.では、今回は2番目のパラメータがi18n: (key, value) => i18n.vm._t(key, value)
に伝わった後、何が起こってプログラムを組織してエラーを報告したのでしょうか.まず、
Vue.use()
が何をしているのか、受け入れられた各パラメータが何をしているのかを理解しなければならない.vueのコードを見始めて、本文のVueのバージョンは2.5.2で、コードを貼って、ファイルの位置:src/core/global-api/use.js
/* @flow */
import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
// 4 : ,
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
// 2 : , : Vue
const args = toArray(arguments, 1)
args.unshift(this)
// 4 : api, .
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
// ,
installedPlugins.push(plugin)
return this
}
}
コードの文法解釈は注釈に書かれていますが、プラグインの名前が
Cwj
であると仮定して、率直に説明します.//
Vue.use(Cwj)
//
Cwj.install(Vue)
// api, , lib install
Cwj(Vue)
// :
Vue.use(Cwj, {
foo: () => bar
})
//
Cwj.install(Vue, {
foo: () => bar
})
まとめ:
Vue.use()
の動作:プラグインのinstall()
の方法を実行し、第1のパラメータはVueであり、残りのパラメータはVue.use()
が受け入れる第2のパラメータおよび以降のパラメータである.また、uiコンポーネントのinstallメソッドの大部分は
Vue.component()
を実行する、ハハ.統合エラーを回避する原理を分析する
Vue.use()
が何をしたか知ったら、iView
のコードにinstall()
の方法を探しに行きます.私がここで見たiViewのバージョンは2.5.0-betaです.1,src/index.js
でinstallメソッドが見つかりました.const install = function(Vue, opts = {}) {
locale.use(opts.locale);
locale.i18n(opts.i18n);
Object.keys(iview).forEach(key => {
Vue.component(key, iview[key]);
});
Vue.prototype.$Loading = LoadingBar;
Vue.prototype.$Message = Message;
Vue.prototype.$Modal = Modal;
Vue.prototype.$Notice = Notice;
Vue.prototype.$Spin = Spin;
};
2行目と3行目で2番目のパラメータの操作が行われていることは明らかですが、
src/locale/index.js
を見てみましょう.export const use = function(l) {
lang = l || lang;
};
export const i18n = function(fn) {
i18nHandler = fn || i18nHandler;
};
わあ、なるほど、
i18n
メソッドが伝達すると、iViewコンポーネントに伝達メソッドが呼び出され、予め定義されたi 18 n処理メソッドではなく、文書の規定に従わなくてもエラーが報告されないのも無理はない.Vue.mixin
では、私たちが伝えた方法は
(key, value) => i18n.vm._t(key, value)
です.ここのi18n.vm._t
はどこから来たのか、私のプロジェクトで問題が発生したファイルがどのようにロードされているかを見てみましょう.Vue.use(VueI18n)
const i18n = new VueI18n({
locale: 'cn',
messages
})
Vue.use(iView, {
i18n: (key, value) => i18n.vm._t(key, value)
})
new Vue({
components: {App},
router,
store,
i18n,
template: ''
}).$mount('#app')
なるほど、この
i18n
は、VueとコンポーネントのVueI18n
に渡された例で、インスタンスには言語パッケージの情報が入っていて、翻訳を推定する際にもi18n.vm._t
メソッドが呼び出されているので、vue-i18n
のコードを見るのが我慢できません.私が見たvue-i 18 nのバージョンは7.3.1です.src/install.js
を見てみましょう.import { warn } from './util'
import extend from './extend'
import mixin from './mixin'
import component from './component'
import { bind, update } from './directive'
export let Vue
export function install (_Vue) {
Vue = _Vue
// ,
const version = (Vue.version && Number(Vue.version.split('.')[0])) || -1
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && install.installed) {
warn('already installed.')
return
}
install.installed = true
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && version < 2) {
warn(`vue-i18n (${install.version}) need to use Vue 2.0 or later (Vue: ${Vue.version}).`)
return
}
// , _i18n Vue.$i18n
Object.defineProperty(Vue.prototype, '$i18n', {
get () { return this._i18n }
})
// 4
extend(Vue)
Vue.mixin(mixin)
Vue.directive('t', { bind, update })
Vue.component(component.name, component)
// merge
// use object-based merge strategy
const strats = Vue.config.optionMergeStrategies
strats.i18n = strats.methods
}
同様に、解釈も注釈に書かれていますが、4つのinstallの核心には私のmixinの方法が詳しくありません.次に、
Vue.mixin()
の方法で何をしたのかを理解してみましょう./* @flow */
import { mergeOptions } from '../util/index'
export function initMixin (Vue: GlobalAPI) {
Vue.mixin = function (mixin: Object) {
this.options = mergeOptions(this.options, mixin)
return this
}
}
文字通りmerge配置、optionsつまり
new Vue()
のときに伝わるパラメータなので、mixinに伝わるのはすべてのVueのサブコンポーネントにoptionsとして扱われる.(このロジックはコードを見ていません.ドキュメントを見ています).$tがどのように動作するか
ロードを行った後、domの補間表現で呼び出すだけで翻訳できます.
$t('hello')
のように、$t
の方法はどのようにすべてのVueのサブコンポーネントにロードされますか.私たちはもう一度整理しなければなりません.以前の章ではいくつかのロード方法について理解していたが、
vue-i18n
のインストール時から分析を開始し、$t
がどのように翻訳するかを検出することを目的としてvue-i18n
のソースコードポケットについて一周する.≪ロード|Load|emdw≫
まずvue-i 18 nがどのようにロードされたかを見てみましょう.
Vue.use(VueI18n)
const i18n = new VueI18n({
locale: 'cn',
messages
})
new Vue({
components: {App},
router,
store,
i18n,
template: ''
}).$mount('#app')
ここで2つに分けます.
Vue.use(VueI18n)
、ここではinstallメソッドnew Vue({ i18n: new VueI18n(options)})
、ここではvue-i18n
のインスタンスをコンポーネントとのoptionsとして設定し、このインスタンスに何があるのか、どこでいつ呼び出されたのかを分析する必要があります.install
前述したように、installのコアの4つの方法は、
Object.defineProperty(Vue.prototype, '$i18n', {
get () { return this._i18n }
})
extend(Vue)
Vue.mixin(mixin)
Vue.directive('t', { bind, update })
Vue.component(component.name, component)
Directiveとcomponentはそれぞれ登録命令と登録コンポーネントであり、ここでは展開せず、
$t
を分析することを目標としている.見てみろjsの
$t
に関するコード:(ファイル内の他のコードは貼り付けられていません)/* @flow */
export default function extend (Vue: any): void {
Vue.prototype.$t = function (key: Path, ...values: any): TranslateResult {
const i18n = this.$i18n
return i18n._t(key, i18n.locale, i18n._getMessages(), this, ...values)
}
}
なるほど、我々が呼び出す
$t('hello')
のソースはVue.$t
であり、Vue.$i18n._t
のメソッドが呼び出される.冒頭のi18n.vm._t
と比較すると、i 18 nはVueI18n
の例であり、Vueのoptionsのi18n
というフィールドに登録されており、同じ_t()
メソッドが呼び出されているが、現在浮上している問題は:i18n.vm._t
は、Vue.$i18n._t
となるではmixinではどのように初期言語パッケージを取得したのでしょうか.ソース:
const options: any = this.$options
、つまりVue.$optionsでは、次の章では、Vueインスタンスの構築時にvue-i 18 nインスタンスをVueインスタンスにロードする方法について説明する.Vueインスタンス構築中にロードされたVueI 18 nインスタンス
src/core/instance/init.js
からのコードを切り取ります. Vue.prototype._init = function (options?: Object) {
const vm: Component = this
// a uid
vm._uid = uid++
let startTag, endTag
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
startTag = `vue-perf-start:${vm._uid}`
endTag = `vue-perf-end:${vm._uid}`
mark(startTag)
}
// a flag to avoid this being observed
vm._isVue = true
// merge options
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
initProxy(vm)
} else {
vm._renderProxy = vm
}
// expose real self
vm._self = vm
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
vm._name = formatComponentName(vm, false)
mark(endTag)
measure(`vue ${vm._name} init`, startTag, endTag)
}
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
}
(ざらざらしてみると)、Vueバーパラメータが判断して自分の
.$options
属性に詰め込む.すなわち、Vue.$options.i18n
は現在、VueI 18 nの一例である.VueI 18 nの構造を見てみましょう.コードは600行ありますが、初期化時に実行されました
const silent = Vue.config.silent
Vue.config.silent = true
this._vm = new Vue({ data })
Vue.config.silent = silent
vuexもそう書いてあるようですが、tメソッドはこのファイルに書かれていますが、どのようにロードするかはvueソースコードを見なければなりません.次回分解するしかありません.
テキストアドレス