ホームページ > ウェブフロントエンド > Vue.js > Vue3.2のエクスポーズとは何ですか?用途は何ですか?

Vue3.2のエクスポーズとは何ですか?用途は何ですか?

青灯夜游
リリース: 2022-07-08 20:14:33
転載
1961 人が閲覧しました

Vue3.2 の新しいエクスポーズは何に使用されますか? Vue3.2のエクスポーズツールについては以下の記事がよく分かりますので、お役に立てれば幸いです。

Vue3.2のエクスポーズとは何ですか?用途は何ですか?

Vue 3.2 のリリースでは、expose という新しい合成ツールが提供されています。 (学習ビデオ共有: vue ビデオ チュートリアル)

いくつかのメソッドとプロパティをテンプレートに提供する必要があるコンポーネントを作成したことがありますが、これらのメソッドをコンポーネントに対してプライベートにしたいと考えたことはありますか?親クラスから呼び出すことはできませんか?

オープン ソース コンポーネントまたはライブラリを開発している場合、一部の内部メソッドを非公開にしておくことが必要な場合があります。 Vue 3.2 より前は、オプション API で宣言されたすべてのメソッドやデータなどがパブリックであり、テンプレートがそれにアクセスできたため、これを実現するのは簡単ではありませんでした。

コンポジション API にも同じことが当てはまります。 setup メソッドから返されるものはすべて、親クラスから直接アクセスできます。

Composition API

実際の例を見てみましょう。カウンタを作成し、このカウンタを毎秒更新するコンポーネントがあると想像してください。

** MyCounter.vue**

<template>
    <p>Counter: {{ counter }}</p>

    <button @click="reset">Reset</button>
    <button @click="terminate">☠️</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup () {
    const counter = ref(0)

    const interval = setInterval(() => {
      counter.value++
    }, 1000)

    const reset = () => {
      counter.value = 0
    }

    const terminate = () => {
      clearInterval(interval)
    }

    return {
      counter,
      reset,
      terminate
    }
  }
}
</script>
ログイン後にコピー

構成の観点から、親コンポーネントが必要に応じて reset メソッドを直接呼び出せるようにしたいと考えています --ただし、コンポーネントでのみ使用できる terminate 関数と counter への参照を保持することが望ましいです。

このコンポーネントを App.vue などの親クラスにインスタンス化し、それに ref 参照をアタッチすると、親クラスで reset メソッドを簡単に呼び出すことができます。これは setup から返されますが、terminate とともにすでに公開されています。

App.vue

<template>
  <MyCounter ref="counter" />

  <button @click="reset">Reset from parent</button>
  <button @click="terminate">Terminate from parent</button>
</template>

<script>
import MyCounter from '@/components/MyCounter.vue'

export default {
  name: 'App',
  components: {
    MyCounter
  },
  methods: {
    reset () {
      this.$refs.counter.reset()
    },
    terminate () {
      this.$refs.counter.terminate()
    }
  }
}
</script>
ログイン後にコピー

これを今実行し、リセット ボタンまたは強制終了ボタンをクリックすると、両方とも機能します。

reset 関数のみが使用できるように、親クラスに公開したいもの (expose) を明示的に指定しましょう。

** MyCounter.vue**

<script>
import { ref } from 'vue'

export default {
  setup (props, context) {
    const counter = ref(null)

    const interval = setInterval(() => {
      counter.value++
    }, 1000)

    const reset = () => {
      counter.value = 0
    }

    const terminate = () => {
      console.log(interval)
      clearInterval(interval)
    }

    context.expose({ reset })

    return {
      counter,
      reset,
      terminate
    }
  }
}
</script>
ログイン後にコピー

ここでは、propscontextsetup 関数パラメータに追加しました。 。ここに expose 関数があるため、コンテキストを利用できるようにする必要があります。 { 公開 } のようにリファクタリングを使用することもできます。

次に、context.expose を使用して、このコンポーネントをインスタンス化する親クラスに公開する要素オブジェクトを宣言します。この例では、 reset 関数が利用可能です。

この例を再度実行して [親から終了] ボタンをクリックすると、エラーが発生します。

Uncaught TypeError: this.$refs.counter.terminate is not a function
ログイン後にコピー

terminate 機能は利用できなくなり、プライベート API にアクセスできなくなりました。

オプション API

上記では、composition APIexponse を使用しましたが、このメソッドはオプション API でも使用できます。 。次のように書き換えることができます。

//  MyCounter.vue


export default {
  created () { ... },
  data: () => ({ counter: null }),
  methods: {
    reset () { ... },
    terminate () { ... }
  },
  expose: ['reset']
}
ログイン後にコピー

新しいオプション API プロパティ expose を追加し、文字列 'reset' が公開関数である配列を渡すことができることに注意してください。 。

API レンダリング関数の結合

強力で柔軟なコンポーネントを作成する方法は、レンダリング関数の力を利用することです。これは Vue 3 にとって新しいことではありませんが、コンポジション API の確立により、コンポジション API h 関数を setup メソッドから直接返すことができる柔軟性が得られました。

これにより問題が発生します。これは、setup 関数の return ステートメント全体に、コンポーネントが作成しているノードの h## だけが含まれているためです。 # 方法。

現時点で何かを親クラスに公開することを選択すると、前に見たものとは逆の問題に遭遇することになります。 DOM 要素以外は何も返されないため、何も公開されません。

このメソッドを使用するように

MyCounter.vue コンポーネントをオーバーライドしましょう。

<script>
// The template has been deleted
import { ref, h } from 'vue'

export default {
  setup (props, context) {
    const counter = ref(0)

    const interval = setInterval(() => {
      counter.value++
    }, 1000)

    const reset = () => {
      counter.value = 0
    }

    const terminate = () => {
      clearInterval(interval)
    }

    // context.expose({ reset })

    return () => h('div', [
      h('p', `Counter: ${counter.value}`),
      h('button', { onClick: reset }, 'Reset'),
      h('button', { onClick: terminate }, 'Terminate')
    ])
  }
}
</script>
ログイン後にコピー
DOM 要素を作成するために必要なため、先頭で Vue から

h をインポートしたことに注意してください。

問題を説明するために、

context.expose メソッドが一時的にコメント化されています。

return ステートメントは、前の