One clean approach is to store a snapshot of the form state after preFillEntry() and compare against it later. Instead of manually coding this in every FormObject, you can abstract it once in a base Form class:
public array $original = [];
public function snapshot(): void { $this->original = $this->toArray(); }
public function isDirty(array $only = []): bool { $current = $this->toArray();
if ($only) {
$current = Arr::only($current, $only);
$original = Arr::only($this->original, $only);
} else {
$original = $this->original;
}
return $current !== $original;
}
Then call $this->form->snapshot() after preFillEntry() in mount().
Now every FormObject automatically gets a reusable isDirty() without repeating logic and you can even check only specific fields.