This is the default way to specify props and emits in VueJS:

<script setup lang="ts">
// This is called "runtime declaration"
const props = defineProps({
  modelValue: {
    type: Object as PropType<User>,
    required: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  placeholder: {
    type: String,
    default: '',
  },

});

const emit = defineEmits(['update:modelValue', 'close', 'change', 'input']);
</script>

If you are using TypeScript, the better way to define them is:

<script setup lang="ts">
interface Props {
  modelValue?: User;
  disabled?: boolean;
  placeholder?: string;
}

// Here, we use pure types via a generic type argument
// Also called type-based declaration
const props = withDefaults(defineProps<Props>(), {
  modelValue: null,
  disabled: false,
  placeholder: '',
});

const emit = defineEmits<{
  'update:modelValue': [User];
  close: [];
  change: [number];
  input: [User];
}>();
</script>

The advantage of doing it like this is that you add type-safety in the both the props and the emits.

You can find more info about this in the VueJS documentation.