Flutter GetX 的Watch State功能

28 min read

类似于 Vue的watch ,除了使用 Obx 实现界面数据自动刷新外,GetX 提供了多种手动方式对响应式变量进行数据变化监听

当数据发生变化时执行自定义的逻辑,比如数据变更后重新请求接口等。

  • ever 当数据发生改变时触发
  • everAll 和 “ever “很像,只是监听的是多个响应式变量的变化,当其中一个发生变化就会触发回调
  • once 只在变量第一次被改变时被调用
  • debounce 防抖,即延迟一定时间调用,且在规定时间内只有最后一次改变会触发回调。如设置时间为 1 秒,发生了3次数据变化,每次间隔500毫秒,则只有最后一次变化会触发回调。
  • interval 时间间隔内只有最后一次变化会触发回调。如设置时间间隔为1秒,则在1秒内无论点击多少次都只有最后一次会触发回调,然后进入下一次的时间间隔。

使用方式:

///每次`count`变化时调用。
ever(count, (newValue) => print("$newValue has been changed"));

///只有在变量count在第一次被改变时才会被调用。
once(count, (newValue) => print("$newValue was changed once"));

///防DDos - 每当用户停止输入1秒时调用,例如。
debounce(count, (newValue) => print("debouce$newValue"), time: Duration(seconds: 1));

///忽略1秒内的所有变化,只有最后一次会触发回调。
interval(count, (newValue) => print("interval $newValue"), time: Duration(seconds: 1));

使用响应式变量实现计数器功能:

class CounterPage extends StatelessWidget {
  var count = 0.obs;
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Counter"),
      ),
      body: Center(
        child: Obx(() => Text("${count.value}", style: const TextStyle(fontSize: 50))),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () => count ++,
      ),
    );
  }
}

上述代码就实现了简单的计数器功能,仔细查看发现并没有使用 StatefulWidget 也能实现计数的自动更新。这就是响应式变量的强大之处。

class Controller extends GetxController{
  var name = "".obs;
  var age = 18.obs;

  @override
  void onInit() {
    /// 每次`name`变化时调用。
    ever(name, (callback)=> null);

    /// 每次监听多个值变化时调用。
    everAll([name,age], (callback) => null);

    /// 只有在变量第一次被改变时才会被调用
    once(name, (callback) => null);

    /// 场景:变量频繁改变,如果用户多次输入、多次点击等。 防DDos - 当变量停止变化1秒后调用,
    /// 例如:搜索功能。用户输入完整单词后再执行搜索操作,而不是用户每输入一个字符就要进行一次操作
    debounce(name, (callback) => null,time: const Duration(seconds: 1));

    /// 忽略指定时间内变量的所有变化
    interval(name, (callback) => null,time: const Duration(seconds: 1));

    super.onInit();
  }
}