Vue 3の新しい機能と変更点・全9件

こんにちは❗フリーランス・エンジニアの 九保すこひ です。

さてさて、前回「Bootstrap v5がどうなるのか調査してみた」という記事を公開しましたが、実は今後のリリースでもうひとつ気になるものがあります。

それは、JavaScript開発の強力な味方、

「Vue.js」の新バージョン(v3)

です。

Vue 3については、以前からたびたび情報が出てましたがついにアルファ版が利用できるようになりました。(2020.3.26現在)

そこで!

今回は、近い将来リリースされるであろうVue 3の使い方をまとめてみることにしました。

ぜひ参考にしていただけると嬉しいです😊✨

(なお、今後内容が変更になる可能性がありますので、ご注意ください)

「ついに来ました Vue 3❗」

Vueインスタンスの作り方が変わった

これまで、Vueアプリをつくる場合このような書き方をしていました。

new Vue({
    el: '#app'
});

それが、今回のアップデートからは、createApp()を使うようになります。

import { createApp } from 'vue'

createApp({
    // ここに各種設定
}).mount('#app');

配列やオブジェクトのバインディングが改善された

これまでのちょっとした弱点だったのですが、data変数に存在していないキーを追加してもリアルタイムでHTMLに反映されませんでした。

<html>
<body>
    <div id="app">
        {{ user }}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script>

        new Vue({
            el: '#app',
            data: {
                user: {
                    id: 1,
                    email: 'user@example.com',
                    password: 'secret'
                }
            },
            mounted() {

                this.user.age = 25; // 👈 ageは存在しないので、Vue 2では反映されない

            }
        });

    </script>
</body>
</html>

しかし、これがVue 3では問題なく動くように改善されました。
また、配列の場合もより直感的なコードを書くことができます。

new Vue({
    el: '#app',
    data: {
        names: ['山田太郎', '佐藤次郎']
    },
    mounted() {

        this.names[2] = '田中三郎'; // 👈 Vue 3ならリアルタイムに反映される

    }
});

そして、データの削除も簡単になります。

delete this.user.email; // 👈 emailを削除

なお、Vue 2までのやりかたは次のとおりでした。

Vue.set(this.user, 'age', 25); // Vue 2の追加
Vue.delete(this.user, 'email'); // Vue 2の削除

Portalで別の場所にコンテンツを表示できるようになった

Portalは新しく追加された機能で、簡単に言うと「別の場所で表示できる」機能です。

例えば、次の例を見てください。

<div id="app">
    <!-- Vueのエリア内 -->
    <Portal target="#footer">フッターです!</Portal>
</div>

<div id="footer"></div>

実はこの例では、<Portal> .. </Portal>の場所には何も表示されず、一番下の<div id="footer"> .. </div>表示されることになります。

つまり、Vueが管理するエリア外にコンテンツを「転送」できるというわけです。

しかも、その転送コンテンツにもVueの動きを加えることができるので、例えば、閉じるボタンで表示を消すことも可能です。

そして、Portalの使いみちとして考えられるのが、モーダルやアラート通知です。

コンポーネントへの「v-model」が複数対応になった

これまでは「v-model」はひとつの値だけしかセットできませんでしたが、次のように複数同時にセットできるようになりました。

<UserForm
    v-model:id="user.id"
    v-model:email="user.email"
    v-model:password="user.password"></UserForm>

なお、v-model:に続く名前はコンポーネントのpropsに一致します。

props: ['id', 'email', 'password']

コンポーネントは1つのタグで囲まなくてよくなった

これまでのVueコンポーネントの制約のひとつに「必ず特定のタグで囲んで1つの要素だけにしないといけない」というものがありましたが、これは気にしなくてよくなりました。

<!-- 👇 Vue 3 ではOK -->
<template>
    <div>1つ目</div>
    <div>2つ目</div>
    <div>3つ目</div>
</template>

Composition APIで大規模なコンポーネントがつくりやすくなった

Composition APIは、大規模なコンポーネントをつくる場合や、多人数での開発に向いています。

なぜなら、Composition APIはコードが大量にあっても管理しやすいからです。(逆に言うと、小さなコンポーネントの場合はあまりメリットはありません)

実際の例をみてみましょう❗

読み込み時にデータ100件を取得し、その中から1ページ10件ずつ表示するコンポーネントです。

<template>
    <div v-for="p in filteredPosts">
        <div>
            ID: {{ p.id }}、タイトル: {{ p.title }}
        </div>
    </div>
    <div>
        <button type="button" @click="prevPage">前へ</button>
        {{ pagination.page }}ページ目
        <button type="button" @click="nextPage">次へ</button>
    </div>
</template>

<script>

    import { ref, reactive, computed, watch, onMounted } from 'vue'

    export default {
        setup() {

            // data
            const posts = ref([]);
            const pagination = reactive({
                page: 1,  // 現在のページ
                limit: 10 // 10件ずつ表示
            });

            // methods
            const prevPage = () => {

                return pagination.page--;

            };
            const nextPage = () => {

                return pagination.page++;

            };
            const getPosts = () => {

                fetch('https://jsonplaceholder.typicode.com/posts')
                    .then(response => response.json())
                    .then(data => {

                        posts.value = data;

                    });

            };

            // computed
            const filteredPosts = computed(() => {

                let filteredPosts = [];
                const start = (pagination.page - 1) * pagination.limit;
                const end = start + pagination.limit;

                for(let i = start ; i < end ; i++) {

                    if(posts.value[i] !== undefined) {

                        filteredPosts.push(posts.value[i])

                    }

                }

                return filteredPosts;

            });

            // watch
            watch(posts, (value, oldValue) => {

                console.log('postsが変更されました');

            });

            // mounted
            onMounted(() => {

                getPosts();

            });

            return {
                posts,
                pagination,
                prevPage,
                nextPage,
                filteredPosts
            }

        }
    }

</script>

もうお気づきかもしれませんが、Composition APIといっても以前の書き方が変わっているだけで、Vue 2に慣れていればそれほど難しい変更ではないかと思います。

では、メリットは何かというと「コードの分割(共通化)」がしやすいということです。

例えば、paginationは別のコンポーネントでも使うなら、外部化しておいた方がいいですよね。そんな場合は次のようすることができます。

UserPosts.vue

import pagination from './pagination'

pagination.js

import { reactive } from 'vue'

export default reactive({
    page: 1,  // 現在のページ
    limit: 10 // 10件ずつ表示
});

このようにしておけば、別のコンポーネントで使う場合にすぐ呼び出せますし、なんなら別の開発者も使うことができます。

Suspenseでコンポーネント準備中は代替表示ができるようになった

Suspenseを使うと、コンポーネントの準備中、代替コンテンツを表示できるようになりました。

実際の使い方はこちらです。

<Suspense>
    <template #default>
        <!-- このコンポーネントの準備を待つ -->
        <UserPost></UserPost>
    </template>
    <template #fallback>
        ⏳ 読み込み中...
    </template>
</Suspense>

この例では、UserPostの準備ができらたら自動的に表示が切り替わります。

ちなみに、#fallbackの部分が表示されるのはコンポーネントのasyncが解決されるまでの間で、次のようなコードが必要です。

UserPost.vue

<template>
    {{ post }}
</template>

<script>

    export default {
        async setup () {

            const promise = new Promise((resolve, reject) => {

                setTimeout(() => {

                    resolve({
                        id: 1,
                        title: 'Postタイトル'
                    });

                }, 3000); // 3秒後に実行

            });
            const post = await promise;
            return {
                post
            }

        }
    }
</script>

実際にブラウザで確認すると、まず次のような表示になります。

そして3秒後、表示は自動的にこうなります。

filterはなくなった

次のようなfilter機能はなくなったようです。(ちなみに私はcomputed派でなのでノーダメージでした😉)

{{ message | filterA | filterB }}

TypeScriptをサポートした

TypeScriptは、開発者の間で人気のテクノロジーですので、その流れを受けてVueでも採用されたようです。

おまけ:新しいVueを試す方法

2020.3.26現在、Vue 3はまだ正式にリリースしていませんが、アルファ版を先取りして試してみることができます。

やり方は、まず適当なフォルダで以下のコマンドを実行します。

git clone https://github.com/vuejs/vue-next-webpack-preview.git

そして、/vue-next-webpack-previewフォルダに移動しパッケージをインストールします。

npm install

これで準備は完了です。

後は、同じ場所で次のコマンドを実行すればブラウザで「http://localhost:8080/」にアクセスできるようになります。

npm run dev

おわりに

ということで、今回はVueの次期バージョン3の変更点をまとめてみました。

ちなみに、たくさん追加機能や変更点を紹介したのでVue 2から相当変わっているような感じるかもしれませんが、カンファレンスの動画でも言及されているとおり(13:49あたりです)Vue 3になっても書き換えはしなくてもよさそうです。

また、Vue 3ファイルサイズが小さくなり高速化もしているので利用者にとってもメリットがあるんじゃないでしょうか。

私も根っからのVueファンとして、ドシドシこれからの開発に役立てたいと思います❗

ぜひ皆さんもチェックしてみてくださいね。(もしかすると、変更点があるかもないので、リリース後をおすすめします😉)

ではでは〜!

うーん、正式リリースが待ち遠しい・・・

この記事が役立ちましたらシェアお願いします😊✨ by 九保すこひ
また、わかりにくい部分がありましたらお問い合わせからお気軽にご連絡ください。
(また、個人レッスンも承ってます👍)
このエントリーをはてなブックマークに追加       follow us in feedly