见见

React 如何转 Vue.js

见见 · 2017-06-17翻译 · 1139阅读 原文链接 betsey审校

如果你是一个 React 开发人员,并决定尝试 Vue.js。欢迎参加这场聚会。

React 和 Vue 就像可口可乐和百事可乐,很多你可以在 React 中做的事,也同样可以在 Vue 中做。不过两者仍然有一些重要的概念上的差异,其中一些反映了 Angular 对 Vue 的影响。

接下来的文章中,我将重点讨论下两者的差异,以便你准备好切换到Vue,并且能马上写出高效的代码。

React 和 Vue 之间有多大的区别?

React 和 Vue 的相似性多于差异性:

  • 都是用于创建 UI 的 JavaScript 库

  • 都是快速和轻量级的

  • 都有基于组件的架构

  • 都使用虚拟 DOM

  • 都可以放在单独的 HTML 文件中,或者在更复杂的 Webpack 设置中的一个模块

  • 都有独立但常用的路由器和状态管理库

它们最大的区别在于 Vue 通常使用 HTML 模板文件,而 React 是完全使用 JavaScript。Vue 还有具有可变状态和称为 “reactivity” 的重新渲染的自动系统。

我们将在下面一一道来。

Components

使用 Vue.js,组件将使用 API 方法 .component 进行声明,该方法接收 id 和定义对象的参数。你可能会注意到 Vue 组件中熟悉的方面,以及不太熟悉的方面:

Vue.component('my-component', {

  // Props
  props: [ 'myprop' ],

  // Local state
  data() {
    return {
      firstName: 'John',
      lastName: 'Smith'
    }
  },

  // Computed property
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName;
    }
  },

  // Template
  template: 
    <div>
      <p>Vue components typically have string templates.</p>
      <p>Here's some local state: {{ firstName }}</p>
      <p>Here's a computed value: {{ fullName }}</p>
      <p>Here's a prop passed down from the parent: {{ myprop }}</p>
    </div>
  ,

  // Lifecycle hook
  created() {
    setTimeout(() => {
      this.message = 'Goodbye World'  
    }, 2000);
  }
});

Template

你注意到组件有一个 template 属性,它是一个 HTML 标记的字符串。Vue 库包括一个编译器,它将在运行时将模板字符串转换为 render 函数。这些渲染由虚拟 DOM 实现。

你也可以选择使用模板,而用自定义 render 函数。你甚至可以使用 JSX。但是切换到 Vue 只是为了做这一点好像有点“作”。

生命周期

Vue 中的组件具有和 React 类似的生命周期方法。例如,当组件状态准备就绪时,但在组件已经挂载(mounted)到页面中之前,将会触发 created

一个很大的区别:没有 shouldComponentUpdate。因为 Vue 的响应式系统(reactivity system)不需要它。

Re-rendering

Vue 初始化步骤之一是遍历所有数据属性并将其转换为 gettersetter。如果你看下面的内容,你可以看到 message 数据属性如何添加一个 getset 函数:

Vue 在访问或修改属性时添加了这些 getter 和 setter 来启用依赖关系跟踪和更改通知。

状态管理

在 Vue 中改变一个组件的状态,你不需要 setState 方法,只需要变异(mutate)。

// React
this.setState({ message: 'Hello World' });

// Vue
this.message = 'Hello World';

message 的值被变异(mutation)改变时,它将触发 setterset 方法将设置一个新值,但也将执行一个辅助任务,通知 Vue 值已更改,依赖该页面的任何部分可能需要重新渲染。

如果 message 作为一个 prop 传递给任何组件,Vue 知道它依赖于这个将自动重新渲染。这就是为什么在 Vue 中不需要 shouldComponentUpdate 的原因。

主模板

关于主模板文件,Vue 更像 Angular。与 React 一样,Vue 需要挂载在页面的某个位置。

<body>
  <div id="root"></div>
</body>
// React
ReactDOM.render('...', document.getElementById('root'));

// Vue
new Vue({
  el: '#root'
});

不同于 React 的是,你可以继续添加这个主 index.html ,因为它是根组件的模板。

<div id="root">
  <div>You can add more markup to index.html</div>
  <my-component v-bind:myprop="myval"></my-component>
</div>

还可以通过使用 x-templateinline-template 等 HTML 功能来定义 index.html 中的子组件模板。尽管它将模板与组件定义的其余部分分开,但这不被认为是最佳实践。

指令(directives)

Vue 允许你通过指令逻辑来增强你的模板,再次同 Angular 一样。这些特殊的 HTML 属性拥有 v- 前缀,例如,v-if 用于条件渲染,v-bind 用于将表达式绑定到常规 HTML 属性。

new Vue({
  el: '#app',
  data: {
    mybool: true,
    myval: 'Hello World'
  }
});
<div id="app">
  <div v-if="mybool">This renders if mybool is truthy.</div>
  <my-component v-bind:myprop="myval"></my-component>
</div>

分配给一个指令的值是一个 JavaScript 表达式,所以你可以参考数据属性,包括三元运算符等。

工作流

尽管社区已经建立了create-vue-app,但是 Vue 官方还没有一个与 create-react-app 的等效物。

官方建议使用 vue-cli 初始化项目。它可以从一个简单的项目生成一个 HTML 文件,一个完整的 Webpack + 服务端渲染项目:

$ vue init template-name project-name

单 HTML 文件项目

Vue 作者尤雨溪将他的项目称为“渐进式框架”,因为它可以扩展到复杂的应用程序,或缩小到简单的应用程序。

当然了,React 也可以做到这一点。不同的是,Vue 项目通常使用较少的 ES6 功能,很少使用 JSX,所以通常不需要添加 Babel。此外,Vue 库全部都在一个文件中,没有相应的 ReactDOM 的单独文件。

以下是将 Vue 添加到单个 HTML 文件项目的方法:

<script src="https://unpkg.com/vue/dist/vue.js"></script>

注意:如果你不打算使用模板字符串,因此不需要模板编译器,则会有一个较小的 Vue 构建,省略了这个称为 vue.runtime.js 的文件。大于 20KB。

单文件组件

如果你乐意使用 Webpack 工具作为项目添加构建步骤,则可以使用 Vue 的单文件组件(SFC)。这些文件具有 .vue 扩展名,并将组件模板,JavaScript 配置和样式全部封装在一个文件中:

<template>
  <div class="my-class">{{ message }}</div>
</template>
<script>
  export default {
    data() {
      message: 'Hello World'
    }
  }
</script>
<style>
  .my-class { font-weight: bold; }
</style>

这些毫无疑问是 Vue 最酷的功能之一。因为你使用 HTML 标记获得“正确”的模板,但 JavaScript 正好在那里,因此模板和逻辑之前没有尴尬的分离。

有一个名为 vue-loader 的 Webpack 加载器负责处理 SFC。在构建过程中, 模板被转换为一个渲染函数,因此这是浏览器中精简版 vue.runtime.js 的完美用例。

Redux and more

Vue 还有一个名为 Vuex 的基于 Flux 的状态管理库。再次,它类似于 Redux,但有一些差异。

本文中我没有时间介绍它,将在下周的文章中介绍。添加我的订阅 来接收新的邮件订阅。

相关文章