Svelte 响应式原理

vue中与Svelte响应式写法

计数器

vue

var vm = new Vue({
  data: {
     count: 0
  },
  computed: {
    double: function () {
      return this.count * 2
    }
  }
})

Svelte

  let count = 0;

  function handleClick() {
    count += 1;
  }
	
  $: double = count * 2
</script>

<button on:click={handleClick}>
  Clicked {double} times
</button>

上面例子中每次点击视图都会更新并增加2

Svelte 响应式原理

  • 实现一个todolist

Svelte 响应式原理

  • 原生怎么去实现

然后每次新增/删除/修改任务时,除了修改 tasks 数据,都需要手动触发重新渲染 tasks(当然这样的实现并不好,每次删除/插入太多 DOM 节点性能会有问题

  • react
    页面操作后 有 三步曲
  1. 首先是调度器,这里主要是为了处理优先级(用户点击事件属于高优先级)和合成事件
  2. 第二个部分是 Render 阶段,这里主要是遍历节点,找到需要更新的 Fiber Node,执行 Diff 算法计算需要执行那种类型的操作,打上 effectTag,生成一条带有 effectTag 的 Fiber Node 链表。常说的异步可中断也是发生在这个阶段。
  3. 第三个阶段是 Commit,这一步要做的事情是遍历第二步生成的链表,依次执行对应的操作(是新增,还是删除,还是修改…)
  • vue

Svelte 响应式原理
大致过程是编译过程中收集依赖,基于 Proxy(3.x) ,defineProperty(2.x) 的 getter,setter 实现在数据变更时通知 Watcher。Vue 的实现很酷,每次修改 data 上的数据都像在施魔法。

  • Svelte
    Svelte 源代码主要分成 compiler 和 runtime 两部分

Svelte 响应式原理

例子

<script>
  let name = "world";
  function setName() {
    name = "fesky";
  }
</script>

<h1 on:click={setName}>Hello {name}!</h1>

经过编译之后

前面例子tolist 中 我们在每次修改数据之后,都要手动重新渲染 DOM!我们不提倡这么写法,因为难以维护
而 Svelte Compile 实际上就是在代码编译阶段帮我们实现了这件事!把需要数据变更之后做的事情都分析出来生成原生 JS 代码,运行时就不需要像 Vue Proxy 那样的运行时代码了

Fragment—— DOM 操作

create_fragment里面都有什么

主要看以下四个钩子方法:
c(create) :在这个钩子里面创建 DOM 节点,创建完之后保存在每个 fragment 的闭包内。
m(mount) :挂载 DOM 节点到 target 上,在这里进行事件的板顶。
p(update) :组件数据发生变更时触发,在这个方法里面检查更新。
d(destroy) :移除挂载,取消事件绑定。

编译结果会从 svelte/internal 中引入 text,element,append,detach,listen 等等的方法。源码中可以看到,都是一些非常纯粹的 DOM 操作。

  • $$invalidate

整体思路

  1. 修改数据,调用 $$invalidate 方法
  2. 判断是否相等,标记脏数据,make_dirty
  3. 在 microTask 中触发更新,遍历所有 dirty_component, 更新 DOM 节点
  4. 重置 Dirty

原文链接:https://juejin.cn/post/7234058546572574780 作者:z_c

(0)
上一篇 2023年5月18日 上午10:41
下一篇 2023年5月18日 上午10:51

相关推荐

发表回复

登录后才能评论