The problem is that the old value is not stored anywhere, so there is nothing to compare it to. The only way around that would be to create hidden fields that get the same content as the fields you want to watch. These fields then only get updated if their content is different from the real fields. So they always contain the old status. Or some json files as backup.
Edit: This is a very basic outline, but something like that should work:
kirby()->hook('panel.page.update', function($page) {
$field = $page->some_field()->value();
if($page->content()->hasField('history')) {
$fieldHistory = $page->history()->value();
} else {
$fieldHistory = "";
}
if($field !== $fieldHistory) {
$page->update(array(
'history' => $field,
));
mail('mail@example.com', 'New Data', $field);
}
});