以 React 开发人员身份学习 Vue

2025-06-07

以 React 开发人员身份学习 Vue

React。这是我从 jQuery 领域学习的第一个主流 JavaScript 框架。

我的学习之路充满坎坷。我花了好几个月才最终理解这种陌生的编程方式。

我循序渐进地学习了基础知识,例如状态管理的工作原理以及 React 生命周期的运作方式。随着时间的推移,我逐渐掌握了这些知识,并最终运用它们在黑客马拉松中构建应用程序,以及构建日常生活中使用的工具。

我开始了我的第一份开发工作,加入了一个使用 Vue 的团队。我对这个框架一无所知,感觉自己得重新学习 JavaScript。

这段从 React 过渡到 Vue 的紧张而有趣的新旅程让我获得了以下宝贵的经验教训,我想与大家分享。

安装

Vue 拥有类似 Create-React-App 的 CLI,但开箱即用的设置让你拥有更多控制权。例如,你可以选择是否包含客户端路由或像 Sass 这样的 CSS 预处理器。

样式和语法

React 使用 JSX,它允许您编写类似 HTML 的语法。

使用 Vue 编写代码就像重温了 EJS 或其他模板语言的美好时光。我不再需要编写 HTML 代码,然后再将其转换为 JSX。我可以直接编写 HTML^TM,然后就可以开始编写代码了。

以下是典型 Vue 文件的示例:



<template>
  <div>
    <h1>{{message}}</h1>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        message: "Hello World"
      }
    },
  }
</script>

<style lang="scss" scoped>
  .h1 {
    color: red;
  }
</style>


Enter fullscreen mode Exit fullscreen mode

假设您在顶层声明了您的 Vue 组件,这只会输出红色的“Hello World”字符串。

在 Vue 中,你编写的是单文件组件。按照惯例,你的组件文件将在顶部包含模板声明,然后是包含所有组件逻辑的脚本定义,最后是所有必要的样式声明。

另一方面,React 对文件结构的要求不那么严格。你仍然可以创建单文件组件,但不必再用 HTML 实现模板,用 SCSS 实现样式,而是用 JavaScript 编写所有内容:用 JSX 实现模板,用 CSS-in-JS 实现样式。以下示例演示了这一点:



import React, { Component } from 'react';

export default class MyFirstComponent extends Component {
  state = {
    message: 'Hello World',
  };
  render() {
    return (
      <div>
        <h1 style={styles.color}>{this.state.message}</h1>
      </div>
    );
  }
}

// CSS in JS
const styles = {
  header: {
    color: 'red',
  },
};


Enter fullscreen mode Exit fullscreen mode

但你也可以直接导入一个.css.scss文件。但是使用导入时遇到的问题是污染了全局命名空间。随着你的应用和团队的发展,你的开发同事很可能会使用与你相同的类名。

你可以选择使用像 这样的库styled-components。它提供了类似 Sass 的语法,可以将样式与 JSX 紧密结合。

React 带来了另一系列问题。你该使用函数式组件还是状态组件?默认情况下,最好只使用你需要的部分,但这意味着未来可能需要进行更多重构。这还没考虑到你现在可以用 React Hooks 来代替类组件了。

道具,状态

React 中有一个叫做 props 的东西,它是从父组件加载的数据。还有一个叫做 state 的东西,它是该组件固有的数据。

以下是渲染“Hello World”消息的示例:



// React Parent Component
import React, { Component } from 'react';
import Child from './Child';

export default class Parent extends Component {
  state = {
    message: 'Hello World',
  };
  render() {
    return (
      <div>
        <Child message={this.state.message} />
      </div>
    );
  }
}


Enter fullscreen mode Exit fullscreen mode


// React Child Component
import React from 'react';

const Child = props => {
  return <div>{props.message}</div>;
};
export default Child;


Enter fullscreen mode Exit fullscreen mode

对于 Vue,概念是一样的。但 Vue 更倾向于约定而非配置。也就是说,它有特定的命名约定。在父组件中声明的子组件采用驼峰命名法。当组件添加到 HTML 中时,语法则采用短横线命名法。

例子:



<!-- Vue Parent Component -->
<template>
  <div>
    <child-component :message="message"/>
  </div>
</template>

<script>
  import ChildComponent from './ChildComponent.vue';
  export default {
    data() {
      return {
        message: 'hello world',
      };
    },
    components: {
      ChildComponent,
    },
  };
</script>


Enter fullscreen mode Exit fullscreen mode


<!-- Vue Child Component -->
<template>
  <div>
    {{message}}
  </div>
</template>

<script>
  export default {
    props: {
      message: {
        type: String,
        default: undefined,
      },
    },
  };
</script>


Enter fullscreen mode Exit fullscreen mode

Vue 要求您声明两次子组件,一次在 import 上,另一次在 上Components

React 的不同之处在于少了一个步骤,您只需导入文件然后使用它。

类型强制

我怀念 C# 或 Java 等静态语言的一点是类型强制。JavaScript 是一种动态脚本语言。这意味着它不关心变量是字符串、数字、布尔值还是其他类型。

声明字符串后,您总是可以将其强制转换为数字。这使得大型前端应用的扩展变得困难。因为您可能不知道自己正在处理的数据类型。

React Native 用 解决了这个问题PropTypes。例如<Child/>我们之前制作的组件:



import React from 'react';
import PropTypes from 'prop-types';

const Child = props => {
  return <div>{props.message}</div>;
};

Child.propTypes = {
  message: PropTypes.string.isRequired,
};

export default Child;


Enter fullscreen mode Exit fullscreen mode

React 中的 propTypes 存在一些问题

  • 拼写错误确实很容易
  • 这是可选的
  • 您必须声明进口

由于这些原因,我发现自己忘记使用 propTypes 了。你可以选择在 React 中使用 Typescript,但这只会增加配置设置的时间。

Vue 要求声明 props,并且 propTypes 位于同一位置。在<script>所有其他逻辑所在的标签内

子组件的示例:



<template>
  <div>
    {{message}}
  </div>
</template>

<script>
  export default {
    props: {
      message: {
        type: String,
        default: undefined,
      },
    },
  };
</script>

<style lang="scss" scoped>
</style>


Enter fullscreen mode Exit fullscreen mode

总体而言,这是一个更好的设计,并且使得 Typescript 在 Vue 中不再是必需的。

数据反应性

这个概念让我在 Vue 上犯了好几次错误。在 React 中,一切都是响应式的。这意味着你可以给对象添加属性,当属性发生变化时,React 会调用它的生命周期。

在 Vue 中……情况就不一样了。在 React 中,每次修改状态时,你都可以传递一个全新的完整状态对象。

Vue 的不同之处在于,你可以直接通过方法来改变状态。由于我们本质上会添加副作用,所以你必须在对象中添加新属性时进行声明。

即使用一种叫做的东西Vue.set()

一个常见的例子是,当你从后端加载数据时,需要创建新的数据并返回。

你还必须key为已迭代的组件定义一个值。React / Vue 的工作方式相同,它让库知道在数据发生变化时需要重新渲染哪些部分。

观察者和可观察对象

我一直不太理解设计模式。但“可观察”这个词终于让我明白了。

Vue 有一个叫做 watchers 的东西。它允许你在特定变量每次发生变化时调用一个方法。

然而,有一些需要注意的地方,因为你可能会让观察者监视观察者。这会导致循环引用问题。

Vue 文档对此提出了警告。我自己也曾不小心用输入框监视其他输入框时犯过同样的错误。

React 通过 的生命周期方法来实现观察者componentDidUpdate。你可以在这里选择需要独立观察的项目。

对于 React Hooks 实现,useState是可观察对象的另一种实现

计算属性

这对我来说是一个来自 React 世界的新概念。在 Vue 中,你可以让变量依赖于其他变量。每当依赖项发生变化时,计算属性也会随之改变。

它乍一看似乎很有用,但只有当您不直接修改它时,计算属性才有用。

当您开始需要时,这就是您完全离开计算属性并转向下一个项目的时候......

方法

Vue 中的方法与 React 中的方法相同。这些方法通过扩展自 HTML DOM 事件的事件指令调用。例如,当用户在输入字段中输入文本时@click,触发事件。@input

当计算属性和观察者不适合您的用例时,方法就是您在 Vue 中始终会回退的方法。

方法就像 JavaScript 中的任何函数一样。返回语句是可选的,你可以使用它在后台修改数据。

异步陷阱

这是一个你稍后会在 Vue 和 React 中发现的陷阱。
在 React 中,有一个名为 的内置方法setState()。当setState()它被调用时,它会在后台异步处理。

Vue 没有什么不同,您有一个方法,Vue.nextTick()它等待数据的最新更新值。

我学到的一个教训是,最好在方法中设置局部变量,并且只根据需要改变数据属性。

模板

Vue 中有一个功能叫做templates。你可以在组件中声明<template>插槽。当组件被调用时,你可以在插槽匹配的位置注入 HTML。

这在图书馆工作时非常有用。我可以根据自己的需要注入功能,以获得所需的功能。

模板不会渲染为<div>DOM 中的元素。React 有一种与模板类似的方法,称为片段 (Fragment),但该方法仅限于组件中的第一个元素。

生命周期方法

生命周期方法描述了组件在其生命周期内所做的事情。

以下是您在 Vue 中常用的:

  • mount() - 类似于 React 的 mount() 方法componentDidMount。这通常在使用 Axios/fetch 调用从后端初始化组件中的数据时使用。
  • updated() - 类似于 React 的componentDidUpdate。当你通过组件更新数据时,你需要向后端发送 POST 请求,以保持同步。
  • destroyed() - 类似于 React 的componentWillUnmount。你不需要使用它,但它有助于清理剩余的事件监听器。

钩子

Hooks 让 React 成为一个极其强大的框架。你不再需要使用 redux 来处理状态,只需使用useState()即可。你不再需要处理setState(),还有许多其他全新改进的方法可供使用。

Vue 没有与 Hooks 等价的功能,尽管在撰写本文时有一个 RFC

指令

Vue 的内置指令让开发变得轻而易举。你可以在 HTML 中直接创建可迭代指令。

在 React 中,这通常意味着创建另一个名为“group(s)”的组件,也许还有一个名为“group”的组件。

Vue,你可以直接在 HTML 中引用v-forv-if等。你的逻辑看起来很连贯。

或者,您可以编写自己的指令!这允许您根据需要将功能附加到页面,从而更轻松地更快地进行开发

对于初创公司来说,开发报告系统是一个很好的用例。如果用户点击了某个尚不存在的功能,您可以添加一个弹出窗口,提示“抱歉,我们正在努力开发这个新功能!请稍后再来”。在后台,您可以发送 Axios 请求,通知用户确实需要该功能。

Mixins

有些公司对此深信不疑。它是一个可复用的代码片段库,可以跨多个组件实现。React 开箱即用,没有这样的功能,你可以使用全局可用的回调函数。

发出事件

Props 通过单向数据绑定从父组件传递到子组件。为了在父组件层面处理业务逻辑,通常需要从子组件发出事件。

使用 Vue 有两种不同的方法。

  1. 您可以将函数的引用从父级传递给子级
  2. 从子进程发出事件并在父进程中捕获响应

大多数应用程序通常使用 #2。示例来自触发父组件中方法的按钮



<!-- Parent Component -->
<template>
<ChildComponent @event-emitted="_handleUpdatedEvent"/>
</template>

<script>
import ChildComponent from './components/ChildComponent.vue';

export default {
components: {
ChildComponent,
},
methods: {
_handleUpdatedEvent(val) {
console.log('Button was clicked');
},
},
};
</script>

Enter fullscreen mode Exit fullscreen mode


<!-- Child Component -->
<template>
<div class="hello">
<button @click="$emit('event-emitted')">Click Me</button>
</div>
</template>

Enter fullscreen mode Exit fullscreen mode




全局状态管理

Vue 的 CLI 具有开箱即用添加 Vuex 的功能。

在 React 中,您可以使用传递一组新的状态setState(),Redux 仅通过全局调度/通量架构来扩展它。

在 Vue 中,你可以在后台修改对象。Vuex 也一样,只不过是在全局层面。

Vue 本身具有创建全局事件总线的能力,类似于 React 的上下文 API。

最后的想法

学习 Vue 是学习新编程范式的好方法。

React 中的许多原则也适用于 Vue。但有几点不同,即:

  • 您不会替换您的状态,而是会改变它,这会产生数据反应性和异步陷阱。
  • 新的构造。有一些 React 中不存在的计算属性、观察器和混合宏
  • 您可以按照在常规 HTML 页面中传统方式编写 HTML 和样式。
  • PropTypes 在 Vue 和 React 中是可选的,但 Vue 需要较少的努力来强制执行。
  • 样式。在 Vue 中,你只需编写 Sass 或 CSS,与 React 相比,这非常简单。

这些是 React 和 Vue 的一些区别。一些相似之处包括:

  • 生命周期方法
  • 道具/状态
  • 为迭代项分配键
  • 方法/函数
  • 向上传递事件
文章来源:https://dev.to/vincentntang/learning-vue-as-a-react-developer-385l
PREV
CSS 3D - 沿 z 轴滚动
NEXT
JavaScript 数组函数备忘单 Array.isArray() Array.from() Array.of()