Почему смешивание Razor Pages и VueJs плохое?

Я пытаюсь настроить .NET-проект с использованием Razor Pages и включать vueJs внутри страницы бритвы для всей моей логики.

Что-то вроде этого:

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

Почему это?

Ответ 1

Вы можете это сделать. Иногда вы обязаны это делать, если, как и мы, вы переносите существующую базу кода, и вы не можете сразу конвертировать все. И, как говорит Рон С, это работает хорошо.

Если вы начинаете новый проект, у вас есть роскошь выбора. Причины для поддержки SPA и без бритвы были бы...

  • Реакционная. Приложения SPA обычно чувствуют (намного) более реактивные. Первоначальные рендеринги часто подаются из кеша, прежде чем данные поступят. При первой загрузке все ресурсы поступают в пакет, в один запрос-ответ. Там нет или гораздо меньше, цепочка запросов.

  • Workflow. Webpack, комплектация и горячая перезагрузка великолепны. Вы получаете производственные сборки, с минимизацией, компиляцией функций рендеринга Vue, устранением ошибок стиля 404, ошибки синтаксиса js в ловушке. Цикл от введения ошибки к ее обнаружению значительно сокращен для многих ошибок.

  • Вселенная SPA. Маршрутизация, Vuex, это действительно путь будущего.

  • Чистота

    . Razor и Vue делают подобные вещи в конце дня. Если вы их смешиваете, вам может быть трудно держать голову прямо.

Ответ 2

Смешивать VueJs и Razor Pages не обязательно плохо, это может быть здорово!

Я использую Vue с бритвой для не SPA-страниц, и они хорошо работают вместе. Я выбираю использовать Vue, загружая его через тег сценария из CDN, и я не использую использование WebPack для переноса, я просто пишу свой код в (вздох) ES5. Я выбрал этот подход по следующим причинам.

  • Использование страниц Razor вместо SPA помогает SEO и ранжированию в поисковых системах публичных страниц.
  • Загрузка Vue напрямую из CDN исключает целый стек технологий, ориентированных на Webpack, из кривой обучения, что значительно упрощает освоение системой новых разработчиков.
  • Этот подход по-прежнему обеспечивает реактивное совершенство в разработке пользовательского интерфейса, которое Vue по своей сути вносит в таблицу.
  • Придерживаясь "модели страницы", код, обеспечивающий функциональность сайта, логически группируется вокруг серверной страницы, обеспечивающей эту функциональность.

Поскольку Vue и Razor могут делать много одинаковых вещей, моя цель для общедоступных страниц состоит в том, чтобы использовать Razor для создания максимально близкого к конечному html и использовать Vue для добавления реактивности на страницу. Это обеспечивает большую выгоду SEO для сканеров, которые индексируют страницу, анализируя возвращенный HTML.

Я понимаю, что мое использование Vue совершенно отличается от использования SPA и WebPack, и этот подход часто означает, что я не могу использовать сторонние компоненты Vue, не переделав код немного. Но этот подход упрощает архитектуру программного обеспечения и обеспечивает легкий реактивный пользовательский интерфейс.

Используя этот подход, Razor можно использовать для генерации начального рендеринга HTML с некоторыми тегами, содержащими атрибуты vue. Затем, после загрузки страницы в браузере, Vue вступает во владение и может реконфигурировать эту страницу любым желаемым способом.

Очевидно, что этот подход не будет соответствовать потребностям всех разработчиков или проектов, но в некоторых случаях это довольно хорошая установка.

Еще несколько деталей для интересующихся

Поскольку я использую vue sitewide, мой глобальный файл _layout.aspx отвечает за создание экземпляра vue. Любые функциональные возможности, реализованные в vue, реализованы на этом уровне. Многие страницы имеют специфическую для страницы функциональность vue, это реализовано как mixin на этой странице или mixin в 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>

В приведенном выше примере Vue.component('dlog',... часть js) устанавливает компонент и делает его доступным для страницы.

Код vue на странице _layout.cshtml выглядит примерно так, как показано ниже. Создавая экземпляр Vue в _layout.cshtml, который используется всем сайтом, Vue создается только в одном месте:

_layout.cshtml:

 <script type="text/javascript">
    var app = new Vue({
        el: '#appTemplate',
        mixins: mixinArray,                     //The page adds it 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 с ASP.NET Razor может быть великолепным!