web-dev-qa-db-ja.com

Vue 3コンポジションAPIとVueインスタンスへのアクセス

_main.js_には次のようなものがあります:

_import { myUtilFunc} from './helpers';
Object.defineProperty(Vue.prototype, '$myUtilFunc', { value: myUtilFunc });
_

このように、_this.$myUtilFunc_を使用すると、アプリケーション全体でmyUtilFuncにアクセスできます

しかし、thisにアクセスできない場合、Vue 3のsetup()メソッドで同じことをどのように実現できますか?

5
Stanislav

ダンの答えは正しいですが、私は受け入れられた答えへのコメントで言及された代替案を提供したいと思います。それぞれに長所と短所があるため、ニーズに基づいて選択する必要があります。

以下のコードが機能する理由を理解するには、コンポーネントのツリーで提供されるプロパティが推移的であることを覚えておくことが重要です。つまりinject('foo')は、すべての親でappまで階層を上がっていく 'foo'を探します。中間のラッパーで何も宣言する必要はありません。

したがって、次のようなものを書くことができます。ここで、globalDateFormatter()は、ツリーの下のコンポーネントで使用したい関数の例にすぎません。

main.js

_import { createApp } from 'vue'
import App from './App.vue'

const globalDateFormatter = (date) => {
    return '[' + date.toLocaleString() + ']'
}

const app = createApp(App)
app.provide('globalDateFormatter', globalDateFormatter) // <-- define here
app.mount('#app')
_

そして、いくつかのDeepDownComponent.vue

_<template>
  <p> {{ fmt(new Date()) }} </p>
</template>

<script>
import { inject } from 'vue'
export default {
    setup(){
        const fmt = inject('globalDateFormatter', x => x.toString()) 
        //           ^-- use here, optional 2nd parameter is the default
        return {fmt}
    }
}
</script>
_

もちろん、次の署名を使用すると、provideおよびinjectを直接インポートして使用できます。

_provide<T>(key: InjectionKey<T> | string, value: T): void
_

そして

_inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
_

コードのどこにでも、app.provide()である必要はありません

このように、グローバルストアでさえ値を提供することもできます。必要に応じて、ref()またはreactive()を使用することを忘れないでください。

要するに、依存性注入を好む場合はいつでも、provide/injectは友達です。

1
Alex Pakka