不同框架组件化之间的对比 之 data

430 阅读4分钟

不同框架的对比之,数据系统

  1. 数据定义
  2. 数据更新
  3. 数据更新特点
  4. 数据更新原理

React

  • 受控数据 state
  • 外部数据 props

state 是可变的,但是在 react 中需要手动的调用 setState 方法。或者如果使用钩子函数,需要制定的函数修改。

类组件

import React from "react";
export class App extends React.component {
  constructor() {
    this.state = {
      a: "this is a",
      b: "this is b"
    };
  }

  render() {
    return (
      <div>
        {this.props.a} - {tshi.props.b}
      </div>
    );
  }
}

修改数据,一般配合事件,如:点击事件,和生命周期来修数据。修该数据需要组件的 setState 方法,来进行修改。

函数组件

函数组件使用 hook 初始化 state 和改变 state

import React from "react";

const App = () => {
  const [value, setValue] = React.useState(0);
  const [a, setA] = React.useState("this is a");
  const [bool, setBool] = React.useState(false);

  return (
    <div>
      <div>value</div>
      <div>a</div>
      <div>bool</div>
    </div>
  );
};

问题

  1. 修改数据是同步的还是异步的?

setState 本身不是异步的,React 会因为性能能需求,表现为异步的更改数据

  • 在 react 生命周期或者作用域中是异步的
  • 在 setTimeout、 原生的环境下为同步

要理解 setState 的更新数据原理,看在什么条件,如果在原生事件和 setTimout 中,不会将其放入队列中,直接就执行了,但是如果在合成事件和生命周期中 react 会把 setState 放入队列中,当需要执行其他任务执行完毕之后,我们就才真正指定 setState 更新视图。

Vue

  • 内部可变数据 data
  • 外部单向流数据 props
  • computed 根据现有数据计算新数据
  • watch 监听数据变化
  • 向外传递数据,事件携带数据

Vue 内部数据是响应式,不需要手动的调用 api 来修改数据,直接修改即可。

响应数据的数组的包裹函数

  • push
  • pop
  • shift
  • unshift
  • splice
  • sort
  • reverse

Vue 中将这个方法进行包装,使得 Vue 的数据响应式系统,使用这些方法也能正常响应式,而不需要再分配。

以上是数组的变更方法,就是修该了,返回就是需改后的数组。然而在 js 中还有一些数组会返回一些新的数组;

  • filter
  • concat
  • slice

这些也是被包装的,我们使用的时候需要注意特点

Angular

  • class 组件属性数据
  • input 就收组件外部数据(parent -> child), 输入型数据, 属性发生变化的时候 ngOnChanges 声明周期来判断
  • output 向外触发事件 类型是 eventEmmiter 事件类型, output 需要和 EventEmmiter 一起使用。这个一点和 Vue 很相似。
import { Output, EventEmmiter } from "@angular/core";

@Component({})
export class MyComponent {
  @Output() newItemEvent = new EventEmmiter<string>();

  // 向外事件事件触发器,我们就能在方法向组件外部触发一个事件
  someThing(value: string) {
    this.newItemEvent.emit(value);
  }
}

关于事件触发器,其实就是一个观察者模式, api 如下:

class EventEmitter<T> extends Subject {
  constructor(isAsync?: boolean): EventEmitter<T>;
  emit(value?: T): void;
  subscribe(generatorOrNext?: any, error?: any, complete?: any): Subscription;
}

在模板中定义 someThing 方法

<button (click)="someThing(newItem.value)">Add to parent's list</button>

click 绑定了一个 someThing 方法, 并将 newItem.value 的值传入,此时点击了 button 之后,我们就能在父组件中,获取数据了。

父组件首先要在模板中监听 newItemEvent 事件,然后写这个事件的处理程序。你发现这个其实和 Vue 套路是一样的,数据绑定,事件绑定都是一个套路,Angular 事件系统存在于 Angular 的核心模块中。Vue 的事件系统就是一个 Vue 的实例。所以实例就具备这种能力。

input/output 的标注写法

使用元数据标注

import { Output, EventEmmiter } from "@angular/core";

@Component({
  input: "",
  output: ""
})
export class MyComponent {
  someThing(value: string) {
    this.newItemEvent.emit(value);
  }
}

指定 input/output 别名

import { Output, EventEmmiter } from "@angular/core";

@Component({})
export class MyComponent {
  @Output("alias_a") newItemEvent = new EventEmmiter<string>();

  // 向外事件事件触发器,我们就能在方法向组件外部触发一个事件
  someThing(value: string) {
    this.newItemEvent.emit(value);
  }
}

Svelte

  • 声明变量数据
  • 计算数据 $: 监听变化

data 声明

svelte 中的数据声明和普通的 javascript 变量声明一样。但是它声明之后就是响应式的。

<script>
  let count = 0;
</script>

<div>count</div>

svelte 也有类似于 computed 计算属性, 它使用了我们可能不熟练的语法 javascript label 语法。

label 其实就是一个标记,在循环语句,需要直接调出的时候非常有用。它会直接调出到 label 修饰的语句之后,开始执行。

svelte 使用 $ 作用一个计算属性的 label,$ label 也是是复杂的语句。这些语句在监听数据变化之后会执行

响应式的陷阱

  • push
  • pop
  • shift
  • unshift
  • splice

更改了数组,不会有响应式的效果,我们需要重新分配的方式,才能避免响应式陷阱

小程序

  1. page data
  2. component data
  3. 组件 props

page

Page({
  data: {
    a: "this is a",
    b: "this is b"
  }
});

component

Component({
  // 内部数据
  data: {
    c: "this is c",
    d: "this is d"
  }
});

小程序数据更新

与 React 类似,需要手动的调用 setData 方法,所以小程序,类似于 Vue 和 React 的结合体。

Page({
  data: {
    a: "this is a",
    b: "this is b"
  },
  onReady() {
    this.setData({
      a: "I`m a new A"
    });
  }
});

小结

主要讨论定义数据或者状态, React 中叫状态 State, 有状态 React 组件叫受控组件,控制的就是 State,手动更新数据。Vue, Svelte、Angular 采用响应式原理,重新分配数据直接更新数据。

小程序比较特殊,数据更新也是需要显示的调用 setData 方法。 Vue 定义响应式最为丰富,data/computed/watch/props 等等。React则是以 Props、State 为核心...