web-dev-qa-db-ja.com

Razor PagesとVueJsを混合するのはなぜ悪いことですか?

私は、Razor Pagesを使用して.NETコアプロジェクトをセットアップし、すべてのロジックのrazorページ内にvueJを含めようとしています。

このようなもの:

@{
    ViewData["Title"] = "VueJs With Razor";
}
<h2>@ViewData["Title"].</h2>

<div id="app">
   <span>{{ message }}</span>
</div>

<script>
     new Vue({
        el: '#app',
        data: {
          message : 'Hello vue.js'
        }
    })
</script>

VueとRazorページを混在させることは悪い習慣であり、Razor OR Vueを使用する必要があることを読みました。

どうしてこれなの?

26

あなたはこれを行うことができます。私たちのように、既存のコードベースを移行していて、一度にすべてを変換することができない場合、あなたはそれをしなければならないことがあります。そして、Ron Cが言うように、それはうまく機能します。

新しいプロジェクトを開始する場合、選択の自由があります。 SPAを支持し、カミソリを使用しない理由は...

  • 反応性。 SPAアプリは一般的に(ずっと)より反応的です。多くの場合、最初のレンダリングは、データが到着する前にキャッシュから提供されます。最初のロードでは、すべてのリソースが1つの要求/応答でバンドルで到着します。リクエストチェーンはありません。

  • ワークフロー。 Webpack、バンドル、ホットリロードは素晴らしいです。プロダクションビルドを取得します。縮小、Vueレンダリング関数のコンパイル、404スタイルエラーの排除、js構文エラーがトラップされます。エラーの導入から発見までのサイクルは、多くのエラーについて大幅に短縮されます。

  • SPAユニバース。ルーティング、Vuex、これは本当に未来の道です。

  • 純度。 RazorとVueは、一日の終わりに同様のことを行います。それらを混ぜると、頭をまっすぐに保つのに苦労するかもしれません。

25
bbsimonbb

VueJsとRazor Pagesの混合は必ずしも悪いことではなく、素晴らしいことです!

SPA以外のページにVueをかみそりで使用すると、2つはうまく機能します。 Vueを使用するには、CDNからスクリプトタグを介して読み込むことを選択しますが、WebPackを使用してトランスパイリングすることはせず、単純に(gasp)ES5でコードを記述します。このアプローチを選んだ理由は次のとおりです。

  • SPAではなくRazorページを使用すると、公開ページのSEOおよび検索エンジンのランキングが向上します。
  • VueをCDNから直接ロードすると、学習曲線からWebpack中心のテクノロジーのスタック全体が排除されるため、新しい開発者がシステムの速度を上げるのがはるかに容易になります。
  • このアプローチは、Vueが本質的にテーブルにもたらすUI開発に対する反応性の良さを提供します。
  • 「ページモデル」を維持することにより、サイトの機能を提供するコードは、その機能を提供するバックエンドページの周囲に論理的にグループ化されます。

VueとRazorは多くの同じことを行うことができるので、公開ページの私の目標は、Razorを使用して最終的なhtmlにできるだけ近いものを生成し、Vueを使用してページに反応性を追加します。これにより、返されたHTMLを解析してページのインデックスを作成するクローラーにSEOの大きなメリットがもたらされます。

Vueの使用法は、SPAおよびWebPackのルートを行くこととはかなり異なり、コードを作り直さずにサードパーティのVueコンポーネントを使用できないことを意味することがよくあります。ビット。しかし、このアプローチはソフトウェアアーキテクチャを簡素化し、軽量のリアクティブUIを提供します。

このアプローチを使用することで、Razorは、vue属性を含むいくつかのタグを使用してHTMLの初期レンダリングを生成するために大きく活用できます。次に、ページがブラウザに読み込まれた後、Vueが引き継ぎ、任意の方法でそのページを再構成できます。

明らかに、このアプローチはすべての開発者やプロジェクトのニーズに合うわけではありませんが、いくつかのユースケースでは、非常に素晴らしいセットアップです。

興味のある人のためのもう少し詳細

サイト全体でvueを使用しているため、グローバル_layout.aspxファイルはvueのインスタンス化を担当します。 vueで実装されるサイト全体の機能は、このレベルで実装されます。多くのページにはページ固有のvue機能があり、これはそのページのミックスインまたはそのページによってロードされたjsファイルのミックスインとして実装されます。 _layout.aspxページがVueをインスタンス化すると、グローバルミックスイン配列に登録したすべてのミックスインでインスタンス化されます。 (ページは、そのグローバルミックスイン配列にミックスインをプッシュしました)

.vueファイルは使用しません。必要なコンポーネントは、ページに直接実装されるか、複数のページで使用する必要がある場合は、次のような部分ビューで実装されます。

dlogViewComponent.cshtml:

    @* dlog vue component template*@
    <script type="text/x-template" id="dlogTemplate">
        <div class="dlog" v-show="dlog.visible" v-on:click="dlog.closeBoxVisible ? close() : ''">
            <div class="dlogCell">
                <div class="dlogFrame" @@click.stop="" style="max-width:400px">
                    <i class="icon icon-close-thin-custom dlogCloseIcon" v-if="dlog.closeBoxVisible" @@click="close()"></i>
                    <div class="dlogCloseIconSpace" v-if="dlog.closeBoxVisible"></div>
                    <div class="dlogInner">
                        <div class="dlogTitle" style="float:left" v-text="title"></div>
                        <div class="clear"></div>
                        <div class="dlogContent">
                            <slot></slot>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </script>

    @* Vue dlog component *@
    <script type="text/javascript">
            Vue.component('dlog', {
                template: '#dlogTemplate',
                props: {    //don't mutate these!
                    closeBoxVisible: true,
                    title: 'One'
                },
                data: function () {
                    return {
                        dlog: { //nest the data props below dlog so I can use same names as cooresponding prop
                            closeBoxVisible: (typeof this.closeBoxVisible === 'undefined') ? true : (this.closeBoxVisible == 'true'),
                            title: (typeof this.title === 'undefined') ? '' : this.title,
                            visible: false
                        }
                    }
                },
                methods: {
                    //opens the dialog
                    open: function () {
                        app.hideBusy();        //just in case, no harm if not busy
                        this.dlog.visible = true;
                        var identifyingClass = this.getIdentifyingClass();
                        Vue.nextTick(function () {
                            $("." + identifyingClass).addClass("animateIn");
                            fx.manageDlogOnly();
                        });
                    },
                    //closes the dialog
                    close: function () {
                        fx.prepDlogClose();
                        var identifyingClass = this.getIdentifyingClass();
                        this.dlog.visible = false;
                        $("." + identifyingClass).removeClass("animateIn");
                    },
                    getIdentifyingClass: function () {
                        if (this.$el.classList.length > 1) {
                            //the last class is always our identifying css class.
                            return this.$el.classList[this.$el.classList.length - 1];
                        } else {
                            throw "A dialog must have an identifying class assigned to it.";
                        }
                    }

                }
            });
    </script>

上記では、コンポーネントをインストールしてページで利用できるようにするのは、jsのVue.component( 'dlog'、...部分です。

_layout.cshtmlページのvueコードは、次のコードのようになります。サイト全体で使用される_layout.cshtmlでVueをインスタンス化することにより、Vueはサイト全体の単一の場所でのみインスタンス化されます。

_layout.cshtml:

 <script type="text/javascript">
    var app = new Vue({
        el: '#appTemplate',
        mixins: mixinArray,                     //The page adds it's mixin to mixinArray before this part of the layout executes. 
        data: {
            errorMsg: ''                        //used sitewide for error messages
            //other data used sitewide
        }, 
        methods: {
            //methods that need to be available in vue sitewide, examples below:
            showBusy: function (html) {
                //functionality to show the user that the site is busy with an ajax request.
            },
            hideBusy: function () {
                //functionality to hide the busy spinner and messaging
            }
        },
        created: function () {
             //this method is particularly useful for initializing data.
        }
    });

</script>

ここで私が提供したものは、この非伝統的なアプローチとその利点のかなり明確な絵を描きます。しかし、何人かの人が尋ねたので、関連するブログ記事も書きました: VueJs with ASP.NET Razor Can Be Great!

64
Ron C

Razorビュー内でVueJSテンプレートをリントすることもできます。

https://www.npmjs.com/package/razor-vue-lint

1