Автор: пыль
И Vue, и React в настоящее время являются одними из самых популярных и экологически лучших интерфейсных фреймворков.Причина использования слова «и» в названии состоит в том, чтобы не ставить их на противоположные стороны. В конце концов, сам фреймворк не хорош и не плох, отличается только приложение, и выбор технологии, которая подходит для наших собственных бизнес-сценариев и формирования команды, является нашей главной целью.
В этой статье мы надеемся, что, сравнивая различия в использовании двух фреймворков, разработчики, которые используют только один из фреймворков для разработки, смогут быстро понять и использовать другой фреймворк для удовлетворения потребностей различных технологических стеков, независимо от того, поддерживаете ли вы старый системы или для адаптации к новой экологии (React-Native).
Итак, давайте поговорим о разнице между Vue и React на следующих шагах:
1. Как начать первый шаг?
Vue и React имеют свои собственные инструменты формирования: vue-cli и create-react-app, оба из которых могут помочь нам быстро создать локальную среду разработки Конкретные шаги заключаются в следующем:
vue-cli 3.*
npm install -g @vue/cli
vue create my-project //node版本推荐8.11.0+
// 如果你还是习惯之前2.*版本的话,再安装一个工具即可
npm install -g @vue/cli-init
vue init webpack my-project
Сгенерированная структура проекта похожа, за исключением того, что версия 3.* инкапсулирует ранее предоставленную конфигурацию веб-пакета в собственный файл конфигурации vue.config.js, включая общие baseUrl, outputDir, devServer.proxy и т. д.
Vue-2:
Vue-3:
create-react-app
npm install -g create-react-app
npx create-react-app my-project
Видно, что инкапсуляция create-react-app более тщательная, в основном скрывающая все конфигурации веб-пакетов и контролируемая только package.json. Но для сценариев, требующих гибкой настройки, такая инкапсуляция явно не подходит, можно запуститьnpm run ejectВыпустите упакованную конфигурацию еще раз.
2. Как решить самые основные потребности развития?
Используя скаффолдинг, мы можем очень гладко построить локальную среду разработки, и следующим шагом будет использование их для развития бизнеса. Перед этим мы можем задать вопрос, каковы самые основные требования к разработке?
Мы можем просто обобщить его в трех аспектах, и перед лицом новой структуры вы также можете начать с этих трех аспектов, чтобы увидеть, как обрабатывается структура, чтобы достичь цели быстрого начала работы.
- Рендеринг шаблона: данные, полученные из бэкэнда (или данные уже в JS), визуализируются в DOM в соответствии с определенными правилами.
- Мониторинг событий: отслеживайте действия пользователя, такие как щелчок, перемещение, ввод и т. д.
- Обработка формы: сохраните влияние данных, вызванное поведением пользователя, отправьте его в серверную часть и обработайте возвращенный результат.
Давайте сначала посмотрим, как Vue обрабатывает эти три аспекта.
// 模板渲染,可以直接使用data对象中的数据,利用指令来处理渲染逻辑
<template>
<div class="hello">
<div v-for="(item, index) in list" :key="index">
{{ item.title }}
</div>
// 处理表单,将用户输入的内容赋值到title上
<input v-model="title" />
// 事件监听,用户点击后触发methods中的方法
<button @click="submit">提交</button>
</div>
</template>
<script>
export default {
data () {
return {
list: [
{ title: 'first' },
{ title: 'second' }
],
title: ''
}
},
methods: {
submit () {
this.list.push({ title: this.title })
this.title = ''
}
}
}
</script>
Способ написания React:
import React, { Component } from 'react';
export default class HelloWorld extends Component {
state = {
list: [
{ title: 'first' },
{ title: 'second' },
],
title: '',
};
setTitle = (e) => {
// 需要手动调用setState来进行重绘,否则input的value不会改变
this.setState({ title: e.target.value })
}
submit = (e) => {
const { title, list } = this.state;
list.push({ title });
this.setState({ list, title: '' });
}
render() {
const { title, list } = this.state;
return (
<div className="App">
// react会使用jsx的方式来进行模板的渲染,可混合使用js和html标签
// {}解析js,()解析html
{ list.map((item, index) => (
<div key={index}>{ item.title }</div>
)
)}
// 事件监听 + 表单处理
<input value={title} onChange={this.setTitle} />
<button onClick={this.submit}>增加</button>
</div>
);
}
}
Из приведенных выше двух примеров мы видим, что метод записи Vue немного проще, и нет необходимости вручную использовать определенные функции, такие как setState, для запуска синхронизации данных и шаблонов. Но также из-за ручного запуска React более свободен: мы можем справиться с ним в соответствии с реальной ситуацией и соответствующим образом сократить ненужные перерисовки для оптимизации производительности.
3. Какая разница в жизненном цикле?
Жизненный цикл всегда был очень важным понятием в Vue и React, которое ясно выражает различные процессы компонентов от создания, установки, обновления и уничтожения. В чем разница между ними в деталях, мы можем посмотреть на фотографии на их соответствующих официальных сайтах.
Жизненный цикл Vue выглядит следующим образом:
Жизненный цикл React выглядит следующим образом:
Основной процесс можно условно разделить на:
- Создайте компонент: некоторые предварительные работы, такие как определение состояния компонента, если вам нужно запросить данные, большая часть этого делается в это время.
- Монтирование компонентов: вы можете монтировать компоненты в документе, и вы можете получить настоящий DOM для работы.
- Обновить компонент: Состояние самого компонента при изменении внешне принимаемых параметров.
- Удаление компонента: когда компонент должен быть удален из текущего документа, некоторые события, такие как таймеры, которые отделены от компонента, обычно уничтожаются.
4. Какие общие свойства у Vue больше, чем у React?
Одна из причин, почему Vue прост в использовании и разработке, заключается в том, что он инкапсулирует множество общих операций, и вам нужно просто использовать некоторые свойства для достижения цели. Удобство и свобода иногда являются антонимами: приобретая какие-то функции, вы жертвуете некоторыми, например, общей алгоритмической стратегией смены пространства на время.
Итак, давайте посмотрим, какие общие свойства Vue отсутствуют в React:
computed
Вычисляемые свойства часто используются для централизованного управления результатами нескольких состояний, избегая раскрытия слишком большой логики вычислений в шаблонах или других ссылках. Нам также не нужно знать, когда и как изменяются свойства, от которых зависит вычисляемое свойство, Vue может автоматически отслеживать результат изменения и пересчитывать его. Например:
computed: {
fullName () {
return this.firstName + ' ' + this.lastName;
}
}
####смотреть: Подобно вычисляемым свойствам, вы можете указать отслеживать изменение состояния и получать значения до и после изменения свойства. Например:
watch: {
name (val, oldVal) { // 监听某个属性发生变化
....
}
}
В React вам нужно реализовать эту функцию, вам может потребоваться определить, изменилось ли свойство в componentWillReceiveProps, или активировать измененную бизнес-логику в setState. Например:
componentWillReceiveProps(nextProps) {
if (nextProps.name != this.props.name) { // props中的某个属性发生了变化
....
}
}
####инструкция Директивы в Vue в основном используются для инкапсуляции работы DOM, например, v-if/v-else/v-for в шаблоне; сам React использует jsx для работы с DOM, поэтому такой концепции нет. Давайте рассмотрим пример пользовательской команды, чтобы проиллюстрировать роль следующей команды:
<img v-lazy="img_url" />
directives: {
'lazy': {
inserted: function (el, binding) {
var body = document.body;
var offsetTop = el.offsetTop;
var parent = el.offsetParent;
// 获取绑定元素对于body顶部的距离
while (parent && parent.tagName != 'body') {
offsetTop += parent.offsetTop;
parent = parent.offsetParent;
}
// 若出现在可视区域内,则直接赋值src
if (body.scrollTop + body.clientHeight > offsetTop && body.scrollTop < offsetTop) {
el.src = binding.value;
} else {
// 若暂未出现,则监听window的scroll事件
var scrollFn = function () {
// 出现在区域内才赋值src,并取消事件监听
if (body.scrollTop + body.clientHeight > offsetTop && body.scrollTop < offsetTop) {
el.src = binding.value;
window.removeEventListener('scroll', scrollFn)
}
}
window.addEventListener('scroll', scrollFn)
}
}
}
}
На самом деле, здесь мы тоже можем представить, если мы используем React, как мы можем реализовать функцию ленивой загрузки изображений?
5. Различия между компонентами
В настоящее время можно сказать, что компоненты являются самой базовой единицей в разработке двух фреймворков.Каждый проект содержит корневой компонент, который затем подразделяется путем маршрутизации от страниц к более однофункциональным компонентам. И то, как иметь дело с отношениями между несколькими компонентами в проекте и как эффективно повторно использовать компоненты, стало тем, что должна учитывать структура Давайте сравним сходства и различия между ними в этой ситуации.
компонент связи
Взаимодействие компонентов является наиболее распространенным типом отношений между компонентами и в основном проявляется в том, что родительский компонент передает данные дочернему компоненту, а дочерний компонент вызывает метод родительского компонента для воздействия на родительский компонент. Давайте возьмем пример, чтобы проиллюстрировать разницу в написании между ними:
Способ написания Vue:
// 父组件
<template>
<div class="parent">
<div v-for="(msg, index) in msgs" :key="index">
{{ msg.content }}
</div>
// 通过v-bind可以绑定父组件状态传递给子组件
// 并且可以自定义事件将方法传递给子组件
<child :last="last" @add="add"></child>
</div>
</template>
<script>
import Child from '@/components/PropsEventChild'
export default {
components: {
Child
},
data () {
return {
name: 'parent',
msgs: []
}
},
computed: {
last () {
const { msgs } = this
return msgs.length ? msgs[msgs.length - 1] : undefined
}
},
methods: {
add (msg) {
this.msgs.push(msg)
}
}
}
</script>
// 子组件
<template>
<div class="child">
<input v-model="content" placeholder="请输入" />
<button @click="submit">提交</button>
</div>
</template>
<script>
export default {
// 此处需要定义接受参数的名称
props: ['last'],
data () {
return {
content: ''
}
},
methods: {
submit () {
const time = new Date().getTime()
const { last } = this
if (last && (time - last.time < 10 * 1000)) {
alert('你发言太快了')
return
}
// 通过$emit的方式可以调用父组件传递过来的自定义事件,从而修改父组件的状态
this.$emit('add', { content: this.content, time })
this.content = ''
}
}
}
</script>
Реагировать на написание:
// 父组件
import React, { Component } from 'react';
import Child from './Child'
export default class Parent extends Component {
state = {
msgs: []
};
get last () {
const { msgs } = this.state;
return msgs.length ? msgs[msgs.length - 1] : undefined;
}
add = (msg) => {
const { msgs } = this.state;
msgs.push(msg);
this.setState({ msgs });
};
render() {
const { msgs } = this.state;
return (
<div className="Parent">
{ msgs.map((item, index) => (
<div key={index}>{ item.content }</div>
)
)}
// 直接传递参数和方法
<Child last={this.last} onClick={this.add}/>
</div>
);
}
}
// 子组件
import React, { Component } from 'react';
export default class Child extends Component {
state = {
content: ''
};
setContent = (e) => {
this.setState({ content: e.target.value })
}
submit = (e) => {
const { props: { last }, state: { content } } = this
const time = new Date().getTime()
if (last && (time - last.time < 10 * 1000)) {
alert('你发言太快了')
return
}
// 直接调用传递过来的方法
this.props.onClick({ content, time })
this.setState({ content: '' })
}
render() {
const { content } = this.state;
return (
<div className="Child">
<input value={content} onChange={this.setContent} />
<button onClick={this.submit}>增加</button>
</div>
);
}
}
вложение компонентов
В реальной разработке часто используются некоторые компоненты, которые предоставляют простые функции пользовательского интерфейса, но контент должен определяться бизнесом, например, Modal, Table и т. д. Этот тип компонента часто вложен в бизнес-компоненты, но не влияет на состояние бизнес-компонентов. Vue предоставляет такой способ написания, который может заменить определенную часть UI-компонента бизнес-компонентом, я не буду повторять здесь код, просто перейду к примеру:
Нет в Реакции<slot>Такой синтаксис, но сам компонент может передавать части внутри тега дочерним компонентам как props.children, например:
import React, { Component } from 'react';
import Wrapper from './Wrapper'
export default class Demo extends Component {
state = {
content: '我是Demo组件中的内容'
};
render() {
return (
<div>
<Wrapper>
<div>{ this.state.content }</div>
</Wrapper>
</div>
);
}
}
import React, { Component } from 'react';
export default class Wrapper extends Component {
render() {
return (
<section>
<header>我是Wrapper头部</header>
{ this.props.children }
<footer>我是Wrapper尾部</footer>
</section>
);
}
}
Видно, что this.props.children представляет обернутый тег в родительском компоненте (класс Demo).<div>{ this.state.content }</div>
компоненты без сохранения состояния
Иногда нам может понадобиться, чтобы компонент играл только роль рендеринга и не нуждался в изменении состояния или мониторинге жизненного цикла. Чтобы сохранить производительность, React может просто использовать функции для приема и использования свойств:
const Wrapper = (props) => (
<section>
<header>我是Wrapper头部</header>
{ props.children }
<footer>我是Wrapper尾部</footer>
</section>
)
Аналогичное использование есть и в Vue, добавляя функционал к тегу шаблона, и данные не будут отслеживаться после рендеринга шаблона:
<template functinal>
<section>
<header>我是Wrapper头部</header>
{ props.children }
<footer>我是Wrapper尾部</footer>
</section>
</template>
// 除了template标签之外,该组件已无法使用Vue实例,也就是不能在该.vue文件中使用<script></script>标签。
Связь между компонентами
Так называемая межкомпонентная связь относится только к получению данных, определенных в родительском компоненте, без передачи реквизитов, чтобы глубокие подкомпоненты могли напрямую обращаться к данным верхнего уровня.
React предоставляет такой механизм, как Context, для достижения конкретного кода:
Установить провайдера, определить данные
Установите потребитель, приобретение данных
В Vue есть аналогичный механизм, но в официальной документации указано, что эта функция предназначена для高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。, но мы все же можем вкратце понять, как его использовать:
// 祖先级组件
export default {
name: 'App',
provide: {
theme: 'meicai'
}
}
// 子组件,获取provide中定义的数据
export default {
inject: ['theme']
}
Реагировать на компоненты высшего порядка
Компонент высшего порядка — это концепция в React, называемая HOC (Компонент высшего порядка) Определение: Компонент высшего порядка — это функция, которая принимает компонент в качестве параметра и возвращает новый компонент. Например следующий пример:
const withHeader = (WrappedComponent) =>
class WrapperComponent extends Component {
render() {
return <section>
<header><h1>顶部信息</h1></header>
<WrappedComponent {...this.props} />
</section>
}
}
Параметр WrappedComponent является компонентом React, и мы можем использовать синтаксис декоратора в других компонентах, чтобы использовать этот компонент более высокого порядка:
import React, { Component } from 'react';
import withHeader from './withHeader'
@withHeader // 装饰器写法
class Section extends Component {
state = {
content: '我是SectionOne'
};
render() {
return (
<div>
{ this.state.content }
</div>
);
}
}
Таким образом, окончательный эффект рендеринга этого компонента Section включает в себя такие элементы, как верхняя информация, добавленная в withHeader, а также его собственную структуру DOM.
В дополнение к структурному улучшению подкомпонентов, компоненты более высокого порядка также могут улучшать функции подкомпонентов путем внедрения свойств. В компоненте Form в ant-design используется аналогичное использование. Давайте рассмотрим упрощенный пример ниже. значение для контролируемого компонента и установите onChange:
import React, { Component } from 'react';
// 表单高阶组件
const Form = (Wrapped) =>
class WrapperComponent extends Component {
state = {
fields: {}
};
getFieldValue = (name) => {
return this.state.fields[name];
};
setFieldValue = (name, value) => {
const fields = this.state.fields;
fields[name] = value;
this.setState({ fields });
};
getFieldDecorator = (name, value) => {
const { fields } = this.state;
if (fields[name] === undefined) {
fields[name] = value || '';
this.setState({ fields })
}
return (WrappedInput) =>
React.cloneElement(WrappedInput,
Object.assign({}, WrappedInput.props, { value: fields[name], onChange: (e) => this.setFieldValue(name, e.target.value) }));
};
render () {
const { getFieldValue, getFieldDecorator } = this;
// 注入新的props对象,将高阶组件的方法传入到子组件中
const form = {
state: this.state,
getFieldValue,
getFieldDecorator,
};
return (<Wrapped {...this.props} form={form}></Wrapped>);
}
};
export default Form
// 使用方式
import React, { Component } from 'react';
import Form from './form'
class Demo extends Component {
checkValue = (e) => {
const { getFieldValue } = this.props.form;
console.log(getFieldValue('title'));
}
render() {
const { getFieldDecorator } = this.props.form;
return (
<div>
{ getFieldDecorator('title')(<input />) }
<button onClick={this.checkValue}>获取输入框值</button>
</div>
);
}
}
export default Form(Demo)
№ 6. Управление состоянием Управление состоянием является распространенным шаблоном проектирования при взаимодействии компонентов в крупных проектах, и Vue, и React приняли этот шаблон и имеют свои собственные реализации. Между ними нет большой концептуальной разницы, как видно из их блок-схем:
Блок-схема управления состоянием Vue:
Блок-схема управления состоянием React:
На обеих диаграммах весь процесс показан как единый поток данных, от состояния к представлению карты, представлению (компоненту) для выполнения действия и действию для воздействия на состояние.
Таким образом, в этом разделе просто сравниваются различия между двумя используемыми:
Vue:
Определение состояний и действий
Компоненты, которые используют состояние и имеют действия
React:
Определение состояний и действий
Компоненты, которые используют состояние и имеют действия
7. Резюме
Наконец, давайте рассмотрим, в этой статье в основном сравниваются различия между Vue и React по следующим аспектам:
- Обработка рендеринга, событий и форм по-разному
- Различия в общих свойствах
- Различия между компонентами и их отношениями
- Управление состоянием использует различные
Я надеюсь, что рассмотрение этих аспектов поможет вам быстро понять другой фреймворк.Дела, включенные в эту статью
Оригинальная ссылка:Фирменные блюда Овощи сливы Талант/деталь/78,Вы также можете найти апплет "Техническая группа по продуктам Meicai" в WeChat. Он полон галантерейных товаров и обновляется каждую неделю. Если вы хотите изучить технологии, не пропустите его.