Общие бизнес-сценарии и детали Vue

внешний интерфейс Vue.js jQuery внешний фреймворк

предисловие

В конце прошлого года компании нужно было открыть новое направление бизнеса, и для завершения этой работы ей нужно было использовать новую фронтенд-фреймворковую технологию Vue. Я очень рад быть одним из первопроходцев, до этого у меня не было большого опыта разработки Vue, и я был только на стадии обучения, а интерфейсный фреймворк, который компания всегда использовала, — это jQuery, поэтому у компании нет фреймворка Vue.Опыт разработки осадки. Внешний мир меняется с каждым днем, и меня всегда интересовали новые технологии, поэтому я всегда надеюсь иметь возможность разрабатывать проекты с новыми фреймворками. Я очень рад этой возможности.Хотя предстоит долгий путь, все исследуется с нуля.  

Но что такое "пионер"! Это!


Vue 

Само собой разумеется, Vue — один из самых популярных фреймворков на сегодняшний день. Вот только два предложения для детской обуви, которая только начинается:

  1. Как учиться:
    Я предлагаю вам перейти прямо кОфициальная документация Vue, официальная документация хорошо написана, и кривая обучения довольно гладкая. Это также преимущество Vue. 
  2. На что обратить внимание:
    Понять его рамочную идею. Идея фреймворков предыдущего поколения, представленных jQuery, заключается в непосредственном манипулировании DOM и обновлении представления. Теперь основные интерфейсные фреймворки, представленные Vue и React, самой большой особенностью являютсяуправляемый данными, работа по манипулированию данными и обновлению представлений остается за фреймворком. Эти две идеи совершенно разные. Если вы уже давно общались с jQuery, вам нужно обратить на это внимание. Не поддавайтесь влиянию мышления разработчиков jQuery. При необходимости вы можете отказаться от предыдущего мышления и принять и развиваться с новым образом мышления. Я не буду говорить здесь о том, как начать работу с Vue, просто перейдите к официальной документации, чтобы начать изучение Vue. Здесь я в основном делюсь типичными бизнес-сценариями, решениями и некоторым опытом, полученным в процессе этого проекта, в надежде быть полезным для вас.


Общие бизнес-сценарии

1. Выбор глобальной регистрации и локальной регистрации

Разработка на основе Vue, наиболее популярная из которых — разработка компонентов, которая также является одной из болевых точек разработки интерфейса, решаемых фреймворком. В Vue регистрация компонентов разделена наГлобальная регистрацияа такжеЧастичная регистрация, разница между ними и каковы общие бизнес-сценарии:

  • Глобальная регистрация

    Vue.component('component-name', {
      // ... 选项 ...
    })

    Веб-страница, как правило, базовый функциональный блок, а затем следующая рациональная модель коробки распределения, мы сформируем общую сеть. Эти основные функциональные блоки, а затем ряд основных элементов, таких какbutton Этикетка,inputэтикетки и т.д. Это должен знать каждый. Исходя из этого, вся страница в основном следует принципу унифицированного дизайна страницы.Основные элементы, как правило, предназначены для унификации, но их необходимо повторно использовать в нескольких местах, так что именно здесь вступают в игру глобальные компоненты. Мы инкапсулируем несколько элементов, которые необходимо повторно использовать, в глобальные компоненты и поддерживаем унификацию функций и дизайна, а места, которые необходимо использовать, можно вызывать напрямую без вторичной разработки. Вот где глобальные компоненты пригодятся.

  • Частичная регистрация

    var ComponentA = { /* ... */ }
    new Vue({
      el: '#app',
      components: {
        'component-a': ComponentA
      }
    })
    

    Веб-страница обычно соответствует экземпляру Vue, то есть корневому компоненту, самому внешнему компоненту. Исходя из этого, мы обычно делим функцию на несколько внутренних модулей, таких как заголовок, область содержимого и так далее. Все эти модули являются независимыми компонентами. Это бизнес-сценарий частичной регистрации.Хотя он жертвует определенной степенью возможности повторного использования (но его можно повторно использовать в нескольких местах в одних и тех же внутренних компонентах), он может независимо поддерживать внутренние функции и независимую бизнес-логику. Выделенные таким образом код и бизнес-логика очень ясны, вместо того, чтобы быть избыточными во внешних компонентах.

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

Суммировать:

  • Самая большая особенность глобальных компонентов — повторное использование.Только когда эта функция используется, она может быть зарегистрирована как глобальный компонент, в противном случае это приведет к определенному количеству отходов. Наиболее распространенными бизнес-сценариями являются базовые компоненты, такие какbutton,inputи т.п. На рынке также есть много хороших библиотек компонентов, таких какiView.
  • Самой большой особенностью локальных компонентов является независимое обслуживание связанной бизнес-логики, уменьшающее связанность и повышающее ясность бизнеса.


2. Как понять границы бизнеса

Как упоминалось выше, когда мы разрабатываем компоненты, нам необходимо разделить модули в соответствии с их функциями. Разделение модулей, слишком подробное или недостаточно конкретное, окажет определенное влияние на процесс разработки. Следовательно, как разделить модули, или как уловить функциональные границы модуля и уточнить сферу его деятельности, также требует нашего внимания. Обычно мы можем думать о следующих вопросах:  

  • Разделенный модуль, что он должен делать? Ничего не нужно делать?
  • Что он показывает внешнему миру? Что принимать одновременно? 

После рассмотрения этих вопросов структура модуля в основном ясна.

  1. Что этот модуль должен делать и не должен делать
    Во-первых, мы начнем с этих двух вопросов, которые также должны определить функциональные границы этого модуля. Например, мы проектируем компонент всплывающего окна, мы начинаем с этих двух вопросов, что ему нужно делать, всплывать, отображать содержимое, закрывать, не более того. Ему не нужно заботиться о том, что отображать, это то, что ему не нужно делать. Начиная с этих двух вопросов, чтобы понять функциональную границу модуля, структура разделенного модуля будет более четкой. 
  2. Что модуль выставляет и принимает
    Это на самом деле рассмотреть, как осуществлять передачу данных. В Vue наиболее распространена связь между родителем и дочерним элементом: родительский компонент передает данные дочернему компоненту через реквизиты, а дочерний компонент отправляет информацию родительскому компоненту, вызывая пользовательские события через emit. Это процесс общения между отцом и сыном. 
    Но есть один момент, который легко упустить из виду: когда реквизит является ссылочным типом, в настоящее время передача не является односторонним потоком данных. Поскольку дочерний компонент получает ссылку, он может изменить значение объекта ссылки, и данные родительского компонента изменятся соответствующим образом, поэтому поток данных становится двусторонним.
    Этого делать не следует, дочерний компонент не должен напрямую изменять данные родительского компонента, и когда вы это сделаете, Vue также предложит вам этого не делать. Поэтому в пропсах вообще передается только значение базового типа, а значение ссылочного типа избегается, при этом тип и дефолтное значение лучше всего прописать при определении пропса, и проверить его один раз .
    Но в некоторых случаях передача ссылочного типа более удобна. Лично я делю на две ситуации:
    1. Когда этот компонент повторно используется глобально, например input , button и другие глобально повторно используемые пользовательские компоненты, передаются только базовые типы.
    2. Когда этот компонент используется внутри функциональным модулем, например локально зарегистрированным компонентом, поскольку он ограничен определенным модулем и имеет большой объем данных, удобнее передать ссылочный тип. Но помните, что вы не можете напрямую изменить значение объекта, на который указывает ссылка.
      Если вам нужно оперировать определенным значением этой ссылки, вы можете присвоить это значение данным или вычисляемому атрибуту, а затем перейти к соответствующей операции. (Также это делается для того, чтобы ограничить модификацию данных компонентами верхнего уровня. Преимущество этого в том, что поток данных ясен, и есть только одно место для изменения данных. Также легче отслеживать данные, когда есть Проблема Поскольку структура основана на управлении данными, проблемы, с которыми придется столкнуться Все это связано с данными, поэтому необходимо ограничить структуру, источник, место назначения и модификацию данных или управлять данными.)

Это направление внешнего принятия мыслить. Как насчет того, чтобы выставить это напоказ или что предложить внешнему миру?

Компонентная разработка имеет высокую степень внутренней автономии, поэтому, когда логика поступает к компоненту, после внутренней обработки компонента, необходимо уведомить об этом снаружи. Вот один принцип, о котором следует помнить:

Должен рассказать внешнему миру, что со мной случилось, а не то, что ты собираешься делать? 

Это может быть немного многословно, но если вы хорошенько об этом подумаете, то поймете, что последнее на самом деле определяет внешнее поведение, поэтому связь есть, и такой дизайн неразумен. Первый просто сообщает вовне о том, что с ним произошло, и неважно, что извне реагирует на эту информацию, такой дизайн разумен. Хотя это предложение звучит, оно кажется очень похожим.


3. Конфигурация данных

Как упоминалось ранее, необходимо ограничить структуру, источник, место назначения и модификацию данных или управлять данными. Поскольку данные управляются, мы должны уделять пристальное внимание данным, разумно проектировать структуру данных и управлять данными.Конфигурация данныхЭто метод управления данными, который я чаще всего использую в проектах, фактически его можно увидеть повсюду во многих деталях фреймворка.

чтоКонфигурация данных?

Например, наиболее распространенным бизнес-сценарием является фоновое управление.


Общая структура кода выглядит следующим образом:

<div id="manage" class="manage">
    <div class="header"></div>
    <div class="main">
        <div class="sidebar">
	    <ul class="menu" v-for="menu in menuDef" :key="menu.type">
	        <div class="menu-title">{{ menu.name }}</div>
		<li class="sub-menu" v-for="submenu in menu.submenu" :key="submenu.type">{{ submenu.name }}</li>
	    </ul>
	</div>
	<div class="content">内容区</div>
    </div>
</div>

<script>
    // 二级菜单
    var subServer = [
        { type: 'manage', name: '管理服务', extClass: 'server-manage' },
        { type: 'list', name: '服务列表', extClass: 'server-list' },
    ];
    // 二级菜单
    var subNews = [
        { type: 'internation', name: '国际新闻', extClass: 'i-news' },
        { type: 'home', name: '国内新闻', extClass: 'home-news' },
    ];
    // 一级菜单
    var menu = [
        { type: 'server', name: '服务', extClass: 'server', submenu: subServer },
        { type: 'news', name: '新闻', extClass: 'news', submenu: subNews }
    ];
    // 根实例
    var manage = new Vue({
        el: '#manage',
        data: {
            menuDef: menu
        }
    });
</script>

Это простая страница управления фоном, левая панель имеет ряд пунктов меню, а правая область содержимого меняется в зависимости от левого переключателя меню. Структура меню слева такая же, но данные другие. Это также можно увидеть в этом примере:

  • Связь между структурой страницы и данными. Структура страницы — это только внешнее представление данных, и она меняется в зависимости от структуры данных.
  • Итак, немного больше абстракции, данные абстрагируются от структуры страницы, которая является структурой данных, необходимой для этой страницы.
  • Если мы удалим структуру данных и сохраним ее отдельно, вот о чем я говорю.Конфигурация данных.

Каковы преимущества конфигурации данных?

  • Я обращаю внимание только на структуру данных, а не на структуру страницы.Даже если я добавляю или удаляю пункты меню или изменяю уровень структуры, мне нужно только внести коррективы на уровне данных, и мне не нужно входить на уровень логики. или слой страницы, чтобы внести изменения. 
  • Этот метод вполне удобен для последующего обслуживания. Будь то расширение или обслуживание, это очень удобно. Я помню, что во время разработки моего проекта страница управления фоном претерпела некоторые изменения.Когда PM сказал мне о местах, которые нужно изменить, я в основном изменил его... потому что мне нужно только заменить слой данных. Например, я просто изменяю документ конфигурации.До тех пор, пока документ помечен и написан ясно, любой может легко его изменить. 

Подходящая сцена:

  • Аналогичная структура, только данные разные. 
  • Это подходит для широкого спектра сценариев и в основном может быть реализовано с повторным использованием компонентов. 

Как упоминалось выше, область содержимого справа изменяется в зависимости от переключения меню слева. Эта реализация основана намаршрутизацияРеализовано, Vue также предоставляетvue-routerОфициальная библиотека маршрутизации, конкретная документация также может перейти непосредственно в официальную документацию. Идея здесь в том, что для управления маршрутизацией можно использовать то же самое.Конфигурация данныхСпособ управления элементами конфигурации маршрутизации в одном месте, а также можно вложить с другими структурами данных. Возьмите пример выше, например:

// 路由配置
// compons.serviceManage、compons.serviceList 就是内容区的内容组件
var serviceRoutes = {
    serviceManage: { path: '/serviceManage', name: 'serviceManage', component: compons.serviceManage },
    serviceList: { path: '/serviceList', name: 'serviceList', component: compons.serviceList}
};
// ...

// 菜单项配置
// 二级菜单
var subServer = [
    { type: 'manage', name: '管理服务', extClass: 'server-manage', router: serviceRoutes.serviceManage },
    { type: 'list', name: '服务列表', extClass: 'server-list', router: serviceRoutes.serviceList },
];
// ....

// 如何使用
// 上面配置的路由配置对象全部放进来,下面会循环创建路由对象。
var routerList = [serviceRoutes, articleRoutes, ...];
// 路由配置,循环路由配置
var router = [];
routerList.forEach(router => {
   router.push(router); 
});

// 根实例
var manage = new Vue({
    router,				// 将配置好的路由对象传进来
    el: '#manage',
    data: {
        menuDef: menu
    }
});

При последующем сопровождении этой части вам нужно только сохранить конфигурацию структуры данных и конфигурацию маршрутизации.


4. Как элегантно использовать jQuery

В процессе разработки Vue большую часть времени вам не нужно управлять DOM самостоятельно, вам нужно только обратить внимание на уровень данных, а фреймворк будет обновлять представление через управление данными.

Но в некоторых специальных сценариях вам действительно нужно выполнять некоторые низкоуровневые операции DOM, такие как наведение курсора на модуль для отображения подсказки или наведение курсора на структуру для отображения панели инструментов. Для такого бизнес-сценария вы можете подумать о том, чтобы обрабатывать его внутри модуля.mouseenter а такжеmouseleaveКогда происходит событие, эта часть логики обрабатывается. Это типичный подход JQuery для решения этой проблемы, и у этого решения много недостатков:

  • Мы не можем повторно использовать, лечение вы делаете, просто ограниченный в модуле, другие места не могут быть напрямую повторно использованы. 
  • Высокая связанность, потому что сам бизнес можно выделить и поддерживать как отдельный компонент. Если он также смешан с другими модулями, это приведет к неясности внутренней логики и структуры модуля. 
  • Трудно поддерживать позже.

Что, если это реализовано в Vue?

Vue предоставляет нам настраиваемый интерфейс директив, который очень хорошо решает проблему в этом бизнес-сценарии. В Vue не рекомендуется выполнять некоторые операции DOM непосредственно внутри экземпляра.Если вам нужно выполнить некоторые низкоуровневые операции DOM, вы можете извлечь их в пользовательские директивы. И когда мне нужно его использовать, я могу просто использовать его напрямую, что отлично решает проблемы вышеуказанного решения.

// jQuery 的方式,错误的方式
<div id='app' @mouseenter='handleMouseEnter' @mouseleave='handleMouseLeave'></div>
<div id='tip'></div>
var app = new Vue({
    el: '#app',
    data: {},
    methods: {
        handleMouseEnter: function () {
            document.querySelector('#tip').style.display = 'block';
        },
        handleMouseLeave: function () {
            document.querySelector('#tip').style.display = 'none';
        }
    }
});

// Vue 的方式,正确的选择
<div id='app' v-tip='{ text: tipText }'></div>

Vue.directive('tip', {
    inserted: function(el, binding) {
	var tipDom = document.querySelector('#tip');
	if(tipDom) {
            // 如果已经存在,不需要创建 DOM
            // do something
	} else {
	    // 如果不存在,创建 DOM
            tipDom = document.createElement('div');
            tipDom.setAttribute('id', 'tip');
            document.body.appendChild(tip);
            // do something
	}
	// 为绑定该指令的元素注册事件
	el.addEventListener('mouseenter', function() {
            // do something
	});
	el.addEventListener('mouseleave', function() {
            // do something
	});
    }
});

var app = new Vue({
    el: '#app',
    data: {
        tipText: 'Hello, world!'
    },
});

Это элегантная реализация Vue в этом бизнес-сценарии. Бизнес-логика хорошо разделена на пользовательские инструкции, которые реализуются в одном месте и повторно используются в нескольких местах. Логика кода ясна, связь низкая, а последующее обслуживание простое. Это как весенний ветерок~

Для получения знаний и применения конкретных связанных пользовательских инструкций вы можете проверить их.пользовательская директиваофициальная документация.


конец

В процессе разработки есть много более подробных сценариев, например, как элегантно реализовать анимацию с помощью Vue, общение родитель-потомок, детали, на которые необходимо обратить внимание при общении с братом и т. д. Эти детали относительно тривиальны, и рассказывать о них по порядку будет слишком долго. Позже, если читатели столкнутся с соответствующими проблемами, они также могут написать еще одну страницу, и тогда я свяжусь с вами~

Этот здесь.

Привет мир!


Знаю почти:Чен Юнсен