Vue 3’s setup(), and where the reactivity comes from

The options API organises a component by kind — data here, methods there, watchers below — so one concern is spread across four sections and two concerns are interleaved in all of them.

export default {
  props: { orderId: Number },

  setup(props) {
    const order = ref(null);
    const loading = computed(() => order.value === null);

    watchEffect(async () => {
      order.value = await fetchOrder(props.orderId);
    });

    return { order, loading };
  },
};

setup runs once before the component is created, which means this is not available and never will be — that is deliberate and is what makes the extracted logic reusable. Everything returned is exposed to the template. watchEffect tracks its own dependencies rather than declaring them, which is a genuine improvement over the array React asks for and a different set of surprises.