likes
comments
collection
share

举起Vue2大刀转战React16(一)

作者站长头像
站长
· 阅读数 49

大家好,我是猿小蚁(简称"小蚁"),因为我个人在整个我们这个社会生态中是个很微小的存在,我难以想象一个"离群索居"的人会是什么样子的,就像是蚂蚁和蚁群的关系一样,但蚂蚁个体的力量却是很强大的,它能举起超越自己体中几十倍以上的重物,而我却无法在前端领域中表现的那么强悍的力量,所以我想成为一只小蚂蚁,在强大的合作/协作关系网中变得very strong.

vue2的使用已经两年多了,但react的内容还是一片空白,这片空白同时影响到了自己的职业发展,所以想要扩展一下,从vue2的角度来边学习边对比react。

1. 入门解析

对比项Vue2.xReact16.x
定位一套用于构建用户界面的**渐进式框架,**这是构建web开发的一整套解决方案的集合。特点: 简单、易用、需要额外学习写法用于构建用户界面的 JavaScript ,这是构建web页面的专用库,可以通过一系列不同的组合搭建web开发的解决方案特点:灵活、js的使用方法
渲染方式template模板+vue实例 [详见2.渲染方式]jsx语法 [详见2.渲染方式]
深入渲染模式深入渲染模式深入渲染模式
使用变量和表达式{{变量名/表达式}} -->双大括号{变量名/表达式} --> 单大括号
属性使用动态::propName="propValue" 静态:propName="xxxx"动态: propName={propValue} 静态:propName="xxx"类名: className=....
事件@eventName="handler"onEventName={handler}传参更麻烦: e=> handler(xxx)绑定this也麻烦: handler.bind(this);
条件渲染v-if/v-else-if/v-else指令js的判断方法,例如 {boolean ? <div>hello</div>: null }
列表渲染v-for指令jsx自动展开数组 js的循环方法,返回对应的jsx
使用domref="refName" <--> $refs.refName声明ref: ref={this.testRef} 定义ref: this.testRef = React.createRef() 使用ref: this.testRef

2. 渲染方式

2.1 模板和实例

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
  </head>

  <body>
    <div id="app">{{name}}</div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>
    <script>
      let app = new Vue({
        el: "#app",
        data() {
          return {
            name: "vue页面渲染",
          };
        },
      });
    </script>
  </body>
</html>

2.2 jsx语法

尴尬了, jsx的使用必须借助babel进行转义,这一点上没有vue方便呀!(第一次想要放弃,直接使用vue,何必要使用react呢)

2.2.1 react环境搭建

  1. 初始化前端项目: npm init -y
  2. 安装babel环境及其他依赖:npm i @babel/core @babel/preset-env @babel/preset-react babel-loader clean-webpack-plugin html-webpack-plugin webpack webpack-cli webpack-dev-server -D
  3. 配置webpack:详情见git仓库
  4. 配置babel:详情见git仓库
  5. 在index.html中引入react、reactDOM两个CDN链接, 注意是两个!两个!!两个!!!
<!-- index.html -->
<script crossorig src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

2.2.2 使用jsx语法

// index.js
let name = "react页面渲染";
let element = <div id="app">{name}</div>;
ReactDOM.render(element, document.getElementById("root"));

2.3 总结

  • react的使用是基于两个库和工程化环境,一个库是react.js,一个库是react-dom.js,工程化环境是babel
    • react.js --> react的核心逻辑库
    • react-dom.js --> react渲染逻辑库
    • babel --> 将jsx语法转为浏览器可用语法, 实际上jsx仅仅是React.createElement的语法糖,用来生成虚拟DOM,详细见官网
  • 对于一直使用vue的我们来说, react使用的缺点有:
    • 使用很不爽,需要配置一大堆的环境配置才可以使用
    • 没有唯一的引用源,太麻烦了
  • 但是react优点也很明显:
    • 使用react时,就能明显感受到react的核心逻辑
    • 体现了react的分工明确、自由组合的特点
    • 对于js的深度用户,使用很符合口味

3. 深入渲染模式

以 "todolist" 为目标,以vue和react两种技术同时实现,效果图如下(突出一个简陋,不喜勿喷): 举起Vue2大刀转战React16(一)

3.1 vue版本思路

  • 响应式数据
    • currentTask:绑定在输入框上,表示输入的任务数据
    • tasks:存储所有的任务数据
  • 计算属性:
    • taskings:待完成的任务数据
    • taskeds:已完成的任务数据
  • 方法:
    • getPageHeight():获取待完成列表的高度
    • addTask():新增任务进入待完成列表
    • doComplete(id):将待完成状态的任务改为已完成状态
    • doRedo(id):将已完成状态的任务改为待完成状态
    • doDelete(id):删除指定的任务

3.2 react实现过程

3.2.1 定义数据

let tasks = [
  {
    id: "2",
    text: "待完成示例",
    done: false,
  },
  {
    id: "1",
    text: "已完成示例",
    done: true,
  },
];
let currentTask = "";
let doingRef = React.createRef(); // 显式声明元素引用

**总结:**其中注意关于元素引用,vue中不需要额外声明变量,而react需要显式声明变量,即let doingRef = React.createRef()

3.2.2 定义方法

let getPageHeight = () => { // 计算元素的高度
  alert(window.getComputedStyle(doingRef.current).height);
};

let addTask = () => { // 新增任务
  if (!currentTask) return;
  tasks.unshift({
    id: Date.now(),
    text: currentTask,
    done: false,
  });
  currentTask = "";
  render(tasks);
};

let doComplete = (id) => { // 设置任务已完成状态
  tasks.forEach((task) => {
    if (task.id == id) task.done = true;
  });
  render(tasks);
};

let doRedo = (id) => {	// 设置任务待完成状态
  tasks.forEach((task) => {
    if (task.id == id) task.done = false;
  });
  render(tasks);
};

let doDelete = (id) => { // 删除任务
  tasks.forEach((task, index) => {
    if (task.id == id) tasks.splice(index, 1);
  });
  render(tasks);
};

总结:

  • 每一个任务完成后都要手动调用一下render函数,即进行都会渲染页面;而vue是不需要管调用时机的
  • 通过ref调用元素时,需要主要使用其中的 current属性;而vue中是直接调用的

3.2.3 定义表单行为

let handleChange = (e) => {
  currentTask = e.target.value;
  render(tasks);
};

总结:

  • 每次表单输入时,都要手动显式调用事件函数进行数据状态改变,并重新渲染页面;而vue中不需要,通过v-model实现了数据绑定以及数据响应式。

3.2.4 定义页面内容

function render(tasks) {
  let rootElement = (
    <>
      <div className="add">
        <input
          type="text"
          value={currentTask}
          onChange={(e) => handleChange(e)}
        ></input>
        <button onClick={addTask}>新增</button>
        <button onClick={getPageHeight}>获取页面高度</button>
      </div>
      <div className="list-show" ref={doingRef}>
        <h2>待完成</h2>
        <ul>
          {tasks
            .filter((task) => !task.done)
            .map((task) => (
              <li key={task.id}>
                <span>{task.text}</span>
                <div className="operation">
                  <button onClick={(e) => doDelete(task.id)}>删除</button>
                  <button onClick={(e) => doComplete(task.id)}>done</button>
                </div>
              </li>
            ))}
        </ul>
      </div>
      <div className="list-show">
        <h2>已完成</h2>
        <ul>
          {tasks
            .filter((task) => task.done)
            .map((task) => (
              <li key={task.id}>
                <span>{task.text}</span>
                <div className="operation">
                  <button onClick={(e) => doDelete(task.id)}>删除</button>
                  <button onClick={(e) => doRedo(task.id)}>undone</button>
                </div>
              </li>
            ))}
        </ul>
      </div>
    </>
  );
  ReactDOM.render(rootElement, document.getElementById("root"));
}

总结:

  • 每次数据变化后,都要手动重新执行下页面渲染;而vue中只需要负责数据变化即可,这一点喜欢vue的实现逻辑
  • 类名定义:react中使用className,和html中不一致;而vue中就直接是class
  • 使用变量和表达式: react使用单大括号; 而vue中使用双大括号
  • 事件定义:react中使用"on+事件名"(事件名首字母大写)的方式来声明;而vue通过v-on:事件名或者@事件名的方式,两者有区别,但使用上差不多;但是react中的this需要手动绑定
  • 条件渲染:react可以通过js三元表达式的写法;而vue使用的是v-if/v-else-if/v-else的指令实现;用起来js的写法更贴近使用习惯;
  • 列表渲染:react可以通过js数组方法的写法;而vue使用的是v-for指令实现;两者都需要使用key来指定唯一标识,估计react也是用来做元素diff操作的;

4. 总结

这是第一次全方面对比学习react,主要从基础和组件两方面出发学习react的使用,但发现基础方面就有很大的差别,即渲染方面,因此打算分两篇来整理学习,react学习这就结束第一过程——dom渲染的对比分析,从中学习到了几点:

  • 在使用时就感受到组件是函数或者对象的存在,感觉更接近JavaScript,而vue更像是一门新的语言;
  • react由于jsx语法的存在必须基于babel来解析,所以需要很多前期准备,当然官方提供了脚手架,还没学习——create-react-app
  • react的渲染需要每次手动调用函数, 有点烦;而vue可以自动实现,这一点很爽的。
  • 最后一点:果然是各有各的好,看自己的使用习惯了!!!

后续将继续学习组件部分,敬请期待哟~~~

转载自:https://juejin.cn/post/7138990970317570055
评论
请登录