svelte响应式

231 阅读1分钟

Svelte 的确不像一些其他框架(如 Vue.js)那样具有深度监听功能。Svelte 的反应式机制基于赋值操作,意味着它只会在你直接改变变量值时触发更新。对于对象和数组的深度变化,它不会自动检测到。

不过,你可以通过以下几种方法来实现类似深度监听的效果:

  1. 手动触发更新:当你修改对象或数组的深层次属性时,通过显式地重新赋值来触发更新。

    // 假设你有一个对象
    let obj = { a: 1, b: { c: 2 } };
    
    // 修改对象的深层次属性
    obj.b.c = 3;
    
    // 手动触发更新
    obj = { ...obj };
    
  2. 使用 Svelte 的 $: 语法:你可以利用 $: 声明反应式声明,使其在指定的变量发生变化时执行某些操作。

    let obj = { a: 1, b: { c: 2 } };
    
    // 声明一个反应式语句,监控 obj 的变化
    $: {
      console.log('obj changed', obj);
    }
    
    // 修改对象的深层次属性并手动触发更新
    obj.b.c = 3;
    obj = { ...obj };
    
  3. 使用 Svelte 的 store:如果你需要在整个应用中共享状态并监听深层次变化,可以考虑使用 Svelte 的 writable store。

    import { writable } from 'svelte/store';
    
    // 创建一个 store
    let objStore = writable({ a: 1, b: { c: 2 } });
    
    // 订阅 store 的变化
    objStore.subscribe(value => {
      console.log('objStore changed', value);
    });
    
    // 修改对象的深层次属性并更新 store
    objStore.update(obj => {
      obj.b.c = 3;
      return { ...obj };
    });
    

如果你需要在 Svelte 组件中深度监听一个作为属性传递进来的对象或数组,可以采取以下方法:

  1. 使用 $: 语法结合 JSON.stringify:通过将对象或数组转换为字符串来检测深层次变化。

  2. 手动触发更新:在父组件中手动触发子组件的更新。

以下是详细的实现方法:

方法一:使用 $: 语法结合 JSON.stringify

<!-- Child.svelte -->
<script>
  export let obj;

  // 使用 JSON.stringify 来检测对象的深层次变化
  $: objString = JSON.stringify(obj);
  
  $: {
    // 当 objString 发生变化时,这个代码块会重新运行
    console.log('obj has changed', obj);
  }
</script>

<p>{obj.b.c}</p>
<!-- Parent.svelte -->
<script>
  import Child from './Child.svelte';
  
  let obj = { a: 1, b: { c: 2 } };

  function updateObj() {
    obj.b.c = 3;
    obj = { ...obj }; // 手动触发更新
  }
</script>

<Child {obj} />

<button on:click={updateObj}>Update Object</button>

{obj.b.c}

方法二:手动触发更新

<!-- Child.svelte -->
<script>
  export let obj;
  
  $: {
    console.log('obj has changed', obj);
  }
</script>

<p>{obj.b.c}</p>
<!-- Parent.svelte -->
<script>
  import Child from './Child.svelte';
  
  let obj = { a: 1, b: { c: 2 } };

  function updateObj() {
    obj.b.c = 3;
    obj = { ...obj }; // 手动触发更新
  }
</script>

<Child {obj} />

<button on:click={updateObj}>Update Object</button>

在这两种方法中,第一种方法利用了 JSON.stringify 将对象或数组转换为字符串,通过字符串的变化来检测对象或数组的深层次变化。而第二种方法通过在父组件中手动触发更新来确保子组件能够检测到变化。

根据实际情况和需求选择适合的方法。