Vue 3の構成APIと関心の分離


A novelty worth digging


私はいつも物事を文脈に置くのが一番いいと思います.だからこそ私はVUEの状態について、3.0の前に書いたのです.
しかし、このシリーズの主な主題は、Vue 3の新機能の一つです:構成API.それは私が最も予想するものです、そして、それが我々がそれを議論する最後の時です!

新しいおもちゃ
主題が既に議論されていたので、この記事はシリーズの最短であるべきですmany times 私よりも人々の方法でより面白く、スマート.
組成APIは、あなたのVueのアプリケーションが大きくなるときに発生する2つの共通の問題に答えるために作成されました.

コード編成
これまでに、複雑なロジックで多くのことを意味すると、本当に大きなコンポーネントを維持する必要がありますかdata , computed , methods , などこれらのタイプのコンポーネントを読むしようとすると、主な問題は何をやっているかを追跡することですし、どのようにお互いと対話するのです.現在のオプションAPIを使用すると、Vueインスタンス内で前後移動する必要があります.
Vue 3はvueインスタンスに新しいメソッドを追加することでこの問題を解決しようとします setup . このメソッドは、beforeCreated フックと受信props 議論として.返される値は、使用するテンプレートのすべての利用可能な情報を含むオブジェクトです.
これはあなたが私たちが話しているとしてもdata , computed , watcher , など
まだこのパズルに欠落している部分は、どのように我々は書くのですかdata , computed , watcher , methods そしてもっと新しいsetup 方法?
Vue 3は、それらの反応性データとより多くを作成する新しいツールを提供します:反応性API.
現在のところ、関連性がないかもしれませんが、反応性APIを使用して反応データを作成する方法の小さな例です.
import { ref } from 'vue';

const count = ref(0);

// Accessing ref's value in JS
console.log('Count:', count.value)

// Modifying the value
count.value += 1
ご覧のように、明示的にアクセスする必要がありますref 'sでそれを操作するとき、s値.それは私が少しバグが、しかし、あなたがテンプレートでそうする必要はありませんし、直接我々は後で表示されるように、値にアクセスすることができます.
この動画を見るReactivity API's reference それに含まれる情報については.
が、どのようにこれらの2つのAPIを一緒に合うか?その例を見てみましょう.まず、オプションAPIを使用してそれを書いて、それから私たちはそれを行う.
ブログ投稿の読み込みと表示を管理するコンポーネントがあるとしましょう.ミニマリストのバージョンは次のようになります.
export default {
    name: 'blog-posts',
    data() {
        return {
            posts: [],
            loadingStatus: '',
            error: '',
        };
    },
    computed: {
        blogPostsLoading() {
            return this.loadingStatus === 'loading';
        },
        blogPostsLoadingError() {
            return this.loadingStatus === 'error';
        },
    },
    methods: {
        loadBlogPosts() {
            this.loadingStatus = 'loading';
            fetch(process.env.VUE_APP_POSTS_URL)
                .then((response) => {
                    if (!response.ok) {
                        throw new Error(response.status);
                    }
                    return reponse.json();
                })
                .then((posts) => {
                    this.posts = posts;
                    this.loadingStatus = 'loaded';
                })
                .catch((error) => {
                    this.error = error;
                    this.loadingStatus = 'error';
                });
        },
    },
    created() {
        this.loadBlogPosts();
    },
}
新しい提供されたツールを使用して、我々はすべてのロジックを置くことができますsetup :
import { ref, computed } from 'vue';

export default {
    name: 'blog-posts',
    setup() {
        const loadingStatus = ref('');
        const error = ref('');
        const posts = ref([]);

        const blogPostsLoading = computed(() => {
            return loadingStatus.value === 'loading';
        });
        const blogPostsLoadingError = computed(() => {
            return loadingStatus.value === 'error';
        });

        const loadBlogPosts = () => {
            loadingStatus.value = 'loading';
            fetch(process.env.VUE_APP_POSTS_URL)
                .then((response) => {
                    if (!response.ok) {
                        throw new Error(response.status);
                    }
                    return reponse.json();
                })
                .then((fetchedPosts) => {
                    posts.value = fetchedPosts;
                    loadingStatus.value = 'loaded';
                })
                .catch((apiError) => {
                    error.value = apiError;
                    loadingStatus.value = 'error';
                });
        };

        // Return every information to be use by the template
        return {
            loadingStatus,
            // You can rename those information if needed
            loadingError: error,
            loadBlogPosts,
            blogPostsLoading,
            blogPostsLoadingError,
        };
    },
};
それはいくつかのロジックを持つコンポーネントではあまり有用ではないようですが、それはすでに開発者は、Vueのインスタンスのオプションの間にスクロールせずに異なる部分を追跡することができます.私たちはこの記事の後で次のものを見て、それを最大限に活用する方法を見ます.
ESモジュールを作成することでロジックを抽出することもできますposts.js ) データの管理と有用な情報の公開
import { ref, computed } from 'vue';

export const useBlogPosts = () => {
    const loadingStatus = ref('');
    const error = ref('');
    const posts = ref([]);

    const blogPostsLoading = computed(() => {
        return loadingStatus.value === 'loading';
    });
    const blogPostsLoadingError = computed(() => {
        return loadingStatus.value === 'error';
    });

    const loadBlogPosts = () => {
        loadingStatus.value = 'loading';
        fetch(process.env.VUE_APP_POSTS_URL)
            .then((response) => {
                if (!response.ok) {
                    throw new Error(response.status);
                }
                return reponse.json();
            })
            .then((fetchedPosts) => {
                posts.value = fetchedPosts;
                loadingStatus.value = 'loaded';
            })
            .catch((apiError) => {
                error.value = apiError;
                loadingStatus.value = 'error';
            });
    };

    // Return every information to be use by the consumer (here, the template) 
    return {
        loadingStatus,
        // You can rename those information if needed
        loadingError: error,
        loadBlogPosts,
        blogPostsLoading,
        blogPostsLoadingError,
    };
}
我々のコンポーネントは、モジュールによって提供されるデータに基づいてテンプレートを管理するだけです.懸念の完全分離:
import { useBlogPosts } from './posts.js';

export default {
    name: 'blog-posts',
    setup() {
        const blogPostsInformation = useBlogPosts();
        return {
            loadingStatus: blogPostsInformation.loadingStatus,
            loadingError: blogPostsInformation.loadingError,
            loadBlogPosts: blogPostsInformation.loadBlogPosts,
            blogPostsLoading: blogPostsInformation.blogPostsLoading,
            blogPostsLoadingError: blogPostsInformation.blogPostsLoadingError,
        };
    },
};
再び、それはあなたのコードを明確にし、常に良いです実装から意図を分離するのに役立ちます.
あなたは既にそれについて考えているかもしれませんが、モジュールを作成するこの方法は、ロジックを再利用するのを助けることができます!

論理再利用
我々はすでに多くのコンポーネントによって使用されるロジックを作成するいくつかのツールがあります.Mixins , たとえば、任意のVueインスタンスのオプションを1つまたは複数のコンポーネントに注入するように書くことができます.
これらのアプローチは1つの欠点を共有し、彼らは明快さを欠いている.
あなたはすべてのそれらのすべてを読んでいない限り、どのミックスがインポートオプションを知っていることはありません.VUEインスタンスとグローバルにローカルに注入されたミックスをナビゲートしなければならないので、コンポーネントがどのように動作するかを理解しようとする開発者の悪夢になることができます.また、ミックスのオプションは、混乱を言うことではなく、結び目袋につながるお互いと衝突することができます.
構成APIを使用すると、任意のコンポーネントは、さまざまなモジュールから必要なものを選ぶことができます.明らかにsetup メソッドは、開発者はどこから、さらには意図をよりよく理解するのに役立つ変数の名前を変更されたかを見ることができます.
私は、明快さは、何年も積極的に維持するアプリケーションを書くとき、最も重要な懸念ではないと思います.組成APIは、我々は、エレガントで実用的な方法でそうするためのツールを提供します.

待って、もっと?
つの主要な目標は私にかなり達成されるように見えます、しかし、構成APIはそれらの2つの懸念に還元されてはいけません.
また、私たちのアプリケーションのテスト容易性に恩恵をもたらす、どのように説明しましょう.
Vue 3以前には、コンポーネントをインスタンス化し、必要に応じて依存した依存関係を注入しなければなりません.テストのこの方法は、実際に実装に強く結合されたテストスイートにつながることができます.年齢が不十分で良い方法より有害な方法を行うことができますテストの種類.
現在、ドメインロジックをカプセル化し、使用するデータとメソッドをエクスポートするESモジュールを作成できます.それらのモジュールは、まだVueのAPIを使用するが、コンポーネントのコンテキストでは使用されないので、ほとんど純粋なJavaScriptで記述されます.
我々のテストは、単に我々のコンポーネントと同じようにエクスポートされた情報を消費することができます!

教授法
あなたは私がそれについての全シリーズを書いているという事実に気づいたかもしれません、私は本当にこの新しいAPIに興奮しています.それは私が私のフロントエンドアプリケーションにきれいなコード原則を適用しようとして、長い間持ってきたかゆみを掻きます.私は、それが我々が使用されるならば、我々の構成要素とアプリケーションの品質を途方もなく増やすのを援助すると思います.
しかし、組成APIは、高度な概念です.私は実際の書き込み方法を置き換えるべきではないと思います.また、Vue 3以前に書かれたレガシーコードに遭遇するので、以前の知識はまだ役に立ちます.
私はすでに前の記事でこの問題について議論していますが、それは本当に心に留めておくことが重要です:誰もがほぼ毎日Vueを練習して2年後に3.0を発見するのに十分幸運です.
一部の人々は3.0とVueを使用して起動し、このような全く新しいAPIは、すでに大きなエントリコストに多くを追加します.新参者は、現在、「古典的な」オプションAPIに加えてそれを理解しなければなりません.
どのように、新しいAPIが新人に導入されなければならないと思いますか?私は個人的にはそれはヴィエックスやVueルータとして、後で高度なツールとして導入されるようにする必要がありますと思います.それは知識のしっかりした基盤の上に加えられて、実質的に使われなければなりません.

もう一度、あなたの考えを共有!
新しい組成APIについてどう思いますか?
あなたは、3.0がリリースされるとすぐにそれを使用する準備ができていますか?
すべての人に知らせてください.
現在、主題は理論的に導入されます、次は何ですか?私は私の手を汚して、作文APIを最大限にしようとします.