web-dev-qa-db-fra.com

Pourquoi le mélange de Razor Pages et de VueJs est-il une mauvaise chose?

J'essaie de configurer un projet .NET central en utilisant Razor Pages et d'inclure une vueJs dans la page de rasoir pour toute ma logique.

Quelque chose comme ça:

@{
    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>

J'ai lu que mélanger Vue et les pages Razor est une mauvaise pratique, et il faut utiliser Razor OR Vue.

Pourquoi est-ce?

26
Joel Pinto Ribeiro

Tu peux le faire. Parfois, vous êtes obligé de le faire si, comme nous, vous migrez une base de code existante et que vous ne pouvez pas tout convertir à la fois. Et comme dit Ron C, cela fonctionne bien.

Si vous commencez un nouveau projet, vous avez le luxe de choisir. Les raisons de préférer un spa et aucun rasoir seraient ...

  • Réactivité. Les applications SPA se sentent généralement (beaucoup) plus réactives. Les rendus initiaux sont souvent servis à partir du cache, avant que les données n'arrivent. Lors du premier chargement, toutes les ressources arrivent dans un paquet, dans une requête-réponse. Il n'y a pas ou beaucoup moins de demandes de chaînage.

  • Flux de travail. Webpack, groupage et rechargements à chaud sont excellents. Vous obtenez des versions de production, avec minification, compilation de Vue fonctions de rendu, élimination des erreurs de style 404, les erreurs de syntaxe js sont interceptées. Le cycle de l'introduction d'une erreur à sa découverte est considérablement réduit pour de nombreuses erreurs .

  • Univers SPA. Le routage, Vuex, c’est vraiment la voie de l’avenir.

  • Pureté. Razor et Vue font des choses semblables à la fin de la journée. Si vous les mélangez, vous aurez peut-être du mal à garder la tête droite.

25
bbsimonbb

Mélanger VueJs et Razor Pages n’est pas forcément une mauvaise chose, c’est génial !

J'utilise Vue avec rasoir pour les pages non SPA et les deux fonctionnent bien ensemble. Je choisis d'utiliser Vue en le chargeant via une balise de script à partir d'un CDN et je ne tire pas parti de l'utilisation de WebPack pour la transcription, j'écris simplement mon code dans (gasp) ES5. J'ai choisi cette approche pour les raisons suivantes.

  • Utiliser des pages Razor plutôt qu'un SPA facilite le référencement et le classement dans les moteurs de recherche des pages destinées au public.
  • Le chargement de Vue directement à partir d'un CDN élimine de la courbe d'apprentissage toute une pile de technologies centrées sur Webpack, ce qui permet aux nouveaux développeurs de se familiariser avec les technologies du système.
  • L’approche fournit toujours la qualité réactive pour le développement d’UI que Vue apporte de manière inhérente à la table.
  • En conservant le "modèle de page", le code fournissant les fonctionnalités du site est regroupé de manière logique autour de la page principale fournissant cette fonctionnalité.

Puisque Vue et Razor peuvent faire beaucoup de choses de la même manière, mon objectif pour les pages destinées au public est d’utiliser Razor pour générer le plus près possible du code HTML final, et d’utiliser Vue pour ajouter de la réactivité à la page. Cela offre d'excellents avantages en termes de référencement aux robots qui indexent la page en analysant le code HTML renvoyé.

Je me rends compte que mon utilisation de Vue est assez différente de celle d'un SPA et d'un WebPack et cette approche signifie souvent que je ne peux pas utiliser de composants Vue tiers sans refaire un peu le code. Mais l'approche simplifie l'architecture logicielle et fournit une interface utilisateur réactive légère.

En utilisant cette approche, Razor peut être fortement exploité pour générer le rendu initial du code HTML avec certaines balises contenant les attributs vue. Ensuite, une fois la page chargée dans le navigateur, Vue prend le relais et peut reconfigurer cette page comme vous le souhaitez.

De toute évidence, cette approche ne répondra pas aux besoins de tous les développeurs ou projets, mais dans certains cas d'utilisation, c'est une configuration plutôt agréable.

Quelques détails supplémentaires pour ceux que ça intéresse

Depuis que j'utilise vue sitewide, mon fichier global _layout.aspx est responsable de l'instanciation de la vue. Toute fonctionnalité à l'échelle du site implémentée dans vue est implémentée à ce niveau. De nombreuses pages ont une fonctionnalité spécifique vue, elle est implémentée en tant que mixin sur cette page ou en mixin dans un fichier js chargé par cette page. Lorsque la page _layout.aspx instancie Vue, elle le fait avec tous les mixins que j'ai enregistrés dans un tableau de mixin global. (La page a poussé son mixin sur ce tableau global mixin)

Je n’utilise pas de fichiers .vue. Tous les composants nécessaires sont implémentés soit directement sur la page, soit s’ils doivent être utilisés par plusieurs pages, puis ils sont implémentés dans une vue partielle comme celle ci-dessous:

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>

Dans ce qui précède, c’est le composant Vue.component ('dlog', ... du js qui installe le composant et le met à la disposition de la page.

Le code vue de la page _layout.cshtml ressemble au code ci-dessous. En instanciant Vue sur le _layout.cshtml utilisé par l’ensemble du site, Vue n’est instancié qu’à un seul endroit dans l’ensemble du site:

_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>

Ce que j'ai fourni ici brosse un tableau assez clair de cette approche non traditionnelle et de ses avantages. Cependant, comme plusieurs personnes me l'ont demandé, j'ai également écrit un article de blog connexe: tiliser VueJs avec ASP.NET Razor peut être génial!

64
Ron C

Vous pouvez maintenant aussi insérer les modèles VueJS dans les vues Razor:

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

1
Kristian Mandrup