ホームページ  >  記事  >  ウェブフロントエンド  >  Vue スロットの変更を監視するにはどうすればよいですか?この裏技を試してみてください!

Vue スロットの変更を監視するにはどうすればよいですか?この裏技を試してみてください!

青灯夜游
青灯夜游転載
2022-09-28 19:52:452700ブラウズ

Vue のスロットの変更を監視するにはどうすればよいですか?以下の記事ではVueスロットの変化を監視する方法を紹介していますので、ご参考になれば幸いです。

Vue スロットの変更を監視するにはどうすればよいですか?この裏技を試してみてください!

最近、コンポーネントの内容 (スロット、サブコンポーネントなど) が変更されるたびにコンポーネントの状態を更新する必要があります。コンテキストとしては、入力の有効性ステータスを追跡するフォーム コンポーネントです。

以下のコード スニペットは Options API 形式で書かれていますが、特に指定されている場合を除き、Vue2 と Vue2 の両方で使用できます。 [関連する推奨事項: vuejs ビデオ チュートリアル ]

開始

フォームの状態を制御することから始め、状態に応じてクラスを変更し、次を使用します。 child content38b537b6886351ac721d89624ba185caFilling:

<template>
  <form :class="{ &#39;--invalid&#39;: isInvalid }">
    <slot />
  </form>
</template>

<script>
export default {
  data: () => ({
    isInvalid: false,
  }),
};
</script>

isInvalid プロパティを更新するには、トリガーされたイベントを追加する必要があります。# を使用できます。 ##sumit イベントですが、私は input イベントを使用することを好みます。

フォーム イベントには、フォーカス、ぼかし、入力、選択、変更、リセット、送信などの 7 つがあります。詳細については、この記事をご覧ください:

https://blog.csdn。 net/qq_4379 ...

フォームは

input イベントをトリガーしませんが、"Event Delegate" を使用できます。リスナーを親要素 (ff9c23ada1bcecdd1a0fb5d5a0f18437) にアタッチし、イベントがその子要素 ​​(d5fd7aea971a85678ba271703566ebfd221f08282418e2996498697df914ce4e# #) で発生したときにアタッチします。 #、4750256ae76b6b9d804861d8f69e79d3 など) がトリガーされます。 このコンポーネントの

58cb293b8600657fad49ec2c8d37b472

input イベントがトリガーされるたびに、フォームはイベントをキャプチャします。 <pre class="brush:php;toolbar:false;">&lt;template&gt; &lt;form :class=&quot;{ &amp;#39;--invalid&amp;#39;: isInvalid }&quot; @input=&quot;validate&quot;&gt; &lt;slot /&gt; &lt;/form&gt; &lt;/template&gt; &lt;script&gt; export default { data: () =&gt; ({ isInvalid: false, }), methods: { validate() { // 验证逻辑 } } }; &lt;/script&gt;</pre>検証ロジックは単純な場合もあれば、複雑な場合もあります。デモンストレーションの目的で、この記事では

form.checkValidity()

API を使用して、HTML 検証属性に基づいてフォームが有効かどうかを確認する簡単な方法を使用します。

ff9c23ada1bcecdd1a0fb5d5a0f18437

要素にアクセスするため。 refs または $el 属性を使用できます。わかりやすくするために、この記事では $el を使用します。 <pre class="brush:php;toolbar:false;">&lt;template&gt; &lt;form :class=&quot;{ &amp;#39;--invalid&amp;#39;: isInvalid }&quot; @input=&quot;validate&quot;&gt; &lt;slot /&gt; &lt;/form&gt; &lt;/template&gt; &lt;script&gt; export default { data: () =&gt; ({ isInvalid: false, }), methods: { validate() { this.isInvalid = !this.$el.checkValidity() } } }; &lt;/script&gt;</pre>

質問

ここで少し問題があります。フォームの内容が変更された場合はどうなりますか?フォームの読み込み時に

d5fd7aea971a85678ba271703566ebfd

が DOM に追加されるとどうなりますか? たとえば、このフォーム コンポーネントを

"MyForm"

と呼びます。アプリでは、コンテンツは次のとおりです: <pre class="brush:php;toolbar:false;">// App.vue &lt;template&gt; &lt;MyForm&gt; &lt;input v-model=&quot;showInput&quot; id=&quot;toggle-name&quot; name=&quot;toggle-name&quot; type=&quot;checkbox&quot; /&gt; &lt;label for=&quot;toggle-name&quot;&gt;显示其它 input&lt;/label&gt; &lt;template v-if=&quot;showInput&quot;&gt; &lt;label for=&quot;name&quot;&gt;Name:&lt;/label&gt; &lt;input id=&quot;name&quot; name=&quot;name&quot; required /&gt; &lt;/template&gt; &lt;button type=&quot;submit&quot;&gt;提交&lt;/button&gt; &lt;/MyForm&gt; &lt;/template&gt; &lt;script&gt; import Form from &quot;./components/form.vue&quot;; export default { name: &quot;App&quot;, components: { MyForm: Form, }, data: () =&gt; ({ showInput: false, }), }; &lt;/script&gt;</pre>When

App.vue

条件によって特定の input を非表示にしたり表示したりすることをフォームが認識する必要があります。この場合、input イベントや mounted ライフサイクル フックだけでなく、フォームのコンテンツが変更されたときにその有効性を追跡することを考えます。そうしないと、誤った情報が表示される可能性があります。 Vue のライフサイクル フックに詳しい友人は、

update

を使用して変更を追跡することを考えるかもしれません。理論的には、これは素晴らしいことだと思います。実際には、無限ループが発生し、ブラウザがハングします。

解決策

調査とテストを行った結果、最良の解決策は

MutationObserver

API を使用することです。これは、DOM ツリーへの変更を監視する機能を提供するブラウザの組み込みメソッドです。この API は、ノードの追加または削除、属性の変更、またはテキスト コンテンツの変更を通知できます。 ネイティブメソッドなのでフレームワークに限定されません。

これを使用する場合は、まず

MutationObserver

コンストラクターを使用して新しいオブザーバー インスタンスを作成し、このインスタンスのコールバック関数を指定します。このコールバックは、DOM が変更されるたびに呼び出されます。コールバック関数は 2 つのパラメーターを受け入れます。1 つ目は変更配列、2 つ目はオブザーバー インスタンスです。form コンポーネントを次のように書き換えます: <pre class="brush:php;toolbar:false;">&lt;template&gt; &lt;form :class=&quot;{ &amp;#39;--invalid&amp;#39;: isInvalid }&quot; @input=&quot;validate&quot;&gt; &lt;slot /&gt; &lt;/form&gt; &lt;/template&gt; &lt;script&gt; export default { data: () =&gt; ({ isInvalid: false, }), mounted() { const observer = new MutationObserver(this.validate); observer.observe(this.$el, { childList: true, subtree: true, }); this.observer = observer; }, methods: { validate() { this.isInvalid = !this.$el.checkValidity(); }, }, beforeUnmount() { this.observer.disconnect(); }, }; &lt;/script&gt; &lt;style scoped&gt; &lt;/style&gt;</pre>ここでも # を使用する必要があります。 ##beforeUnmount

ライフサイクル イベントにより

observer が切断され、割り当てられたメモリがすべてクリアされます。 最後に、アクセスしたいコンテンツのプラグイン スロットに isInvalid

ステータスを渡します。これはスコープのスロットとも呼ばれ、非常に便利です。

<template>
  <form :class="{ &#39;--invalid&#39;: isInvalid }" @input="validate">
    <slot v-bind="{ isInvalid }" />
  </form>
</template>

<script>
export default {
  data: () => ({
    isInvalid: false,
  }),
  mounted() {
    const observer = new MutationObserver(this.validate);
    observer.observe(this.$el, {
      childList: true,
      subtree: true,
    });
    this.observer = observer;
  },
  methods: {
    validate() {
      this.isInvalid = !this.$el.checkValidity();
    },
  },
  beforeUnmount() {
    this.observer.disconnect();
  },
};
</script>
このセットアップを使用すると、フォーム コンポーネントに任意の数の input

を追加し、必要な条件付きレンダリング ロジックを追加できます。

input が HTML 検証属性を使用している限り、フォームは有効な状態であるかどうかを追跡します。 さらに、スコープ付きスロットを使用しているため、フォームの状態を親に提供し、親が有効性の変更に反応できるようにします。

たとえば、

App.vue

で、フォームが無効な場合に送信ボタンを「無効」にしたい場合は、次のように記述できます。

<template>
  <MyForm>
    <template slot:default="form">
      <label for="name">Name:</label>
      <input id="name" name="name" required>

      <button
        type="submit"
        :class="{ disabled: form.isInvalid }"
      >
        Submit
      </button>
    </template>
  </MyForm>
</template>
nice~。

この記事があなたの将来の開発に役立つことを願っています。

(学習ビデオ共有: Web フロントエンド開発基本プログラミング ビデオ)

以上がVue スロットの変更を監視するにはどうすればよいですか?この裏技を試してみてください!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。