Back
🕒 4 min read
Blog Post Author

From React to Vue: Culture Shocks as a Frontend Developer (Vue 2 & 3)

Nov 19, 2025
From React to Vue: Culture Shocks as a Frontend Developer (Vue 2 & 3)

From React to Vue 2 & 3: Lessons, Wins, and Culture Shocks as a Frontend Developer

Transitioning from React to Vue has been one of the most rewarding learning experiences of my career. After working extensively with React and Next.js, I joined Rentsync, which maintains high-volume production Vue apps. Experiencing both Vue 2 and Vue 3 has given me a broad perspective on framework evolution, developer ergonomics, and project architecture

React vs Vue: First Impressions

Coming from React, the first thing I noticed was Vue’s template-based syntax. Instead of writing JSX, Vue uses a declarative template style that feels closer to HTML. At first, it felt restrictive, but Vue directives (v-if, v-for, v-bind, v-model) make templates highly readable

<template>
  <div>
    <h2>{{ listing.name }}</h2>
    <p>{{ listing.description }}</p>
    <button @click="toggleFavorite">Favorite</button>
  </div>
</template>

Vue 3's Composition API was a big shift. If React Hooks taught me to think in functions, the Composition API made me think in reactivity. ref() and reactive() feel like useState on steroids — powerful, flexible, and easier to organize when your logic scales

import { ref, computed } from "vue";

const listings = ref([]);
const search = ref("");

const filteredListings = computed(() =>
  listings.value.filter((l) =>
    l.name.toLowerCase().includes(search.value.toLowerCase())
  )
);

Vue 2 uses the Options API. State is declared in data, computed properties in computed, and side effects in watch or lifecycle hooks like mounted. It is more declarative but less flexible than the Composition API

export default {
  data() {
    return {
      listings: [],
      search: ""
    };
  },
  computed: {
    filteredListings() {
      return this.listings.filter(l =>
        l.name.toLowerCase().includes(this.search.toLowerCase())
      );
    }
  }
};

Culture Shocks and Paradigm Shifts

Single File Components (SFCs)

In React, I split components, CSS, and tests into separate files. In Vue 2 and 3, everything lives inside one .vue file — template, script, and style. It felt odd at first, but it reduces context-switching

Reactivity Without Re-Renders

In React, state updates trigger component re-renders. Vue’s reactivity system updates only what changes, without redrawing the entire component tree. This is subtle but highly efficient

DOM Updates and the Next Tick Shocker

One of the most surprising things in Vue 2 was how DOM updates are applied asynchronously. Vue batches updates and applies them on the next "tick" of its internal queue. React re-renders are synchronous in the same render cycle, but in Vue, the DOM reflects changes only after the next tick

// Vue 2 example
export default {
  data() {
    return { count: 0 };
  },
  methods: {
    increment() {
      this.count++;
      console.log(this.$refs.count.textContent); // Still old value
      this.$nextTick(() => {
        console.log(this.$refs.count.textContent); // Updated value
      });
    }
  }
};
<template>
  <div>
    <span ref="count">{{ count }}</span>
    <button @click="increment">Increment</button>
  </div>
</template>

Vue 3 has nextTick() imported from the framework, but the concept is the same — the DOM update happens after the next tick

import { ref, nextTick } from "vue";

const count = ref(0);

function increment() {
  count.value++;
  console.log(document.querySelector("#count").textContent); // Old value
  nextTick(() => {
    console.log(document.querySelector("#count").textContent); // Updated
  });
}

Props and Emits Over Prop Drilling

Vue 2 and 3 support props and custom events. The pattern reduces deep prop drilling and clarifies data flow

// Vue 3
const props = defineProps(["listing"]);
const emit = defineEmits(["favorite"]);

// Vue 2
props: ["listing"],
methods: {
  favorite() {
    this.$emit("favorite");
  }
}

SCSS and Scoped Styles

Vue’s scoped styles help avoid collisions while keeping SCSS maintainable

<style scoped lang="scss">
.card {
  border-radius: 10px;
  padding: 1rem;
  transition: all 0.3s ease;

  &:hover {
    background-color: #f5f5f5;
  }
}
</style>

TypeScript in Vue

TypeScript is optional in Vue 2 (with class-style components) but native in Vue 3. Typing ensures maintainability across components

interface Listing {
  id: number;
  name: string;
  description: string;
  image: string;
  price: number;
}

Vue 3 Composition API makes typing refs, computed values, and props straightforward

import { ref, computed } from "vue";

const listings = ref<Listing[]>([]);
const averagePrice = computed(() => {
  return listings.value.length
    ? listings.value.reduce((a, c) => a + c.price, 0) / listings.value.length
    : 0;
});

React Hooks vs Vue Reactivity

// React
const [count, setCount] = useState(0);
useEffect(() => console.log(count), [count]);
// Vue 3
const count = ref(0);
watch(count, (value) => console.log(value));
// Vue 2
data() {
  return { count: 0 };
},
watch: {
  count(newVal) {
    console.log(newVal);
  }
}

Wins

Predictable reactivity — The data-driven model is more intuitive once you understand how Vue tracks dependencies

Simplicity — The framework has strong conventions out of the box, reducing boilerplate

Styling — Scoped SCSS and built-in transitions make design work smoother

Community — Vue’s documentation is crystal clear and beginner-friendly

Cons

Fewer ecosystem tools compared to React (though Vite + Pinia make up for a lot)

Less familiar syntax at first, especially when mixing Composition and Options APIs

Template limitations when you are used to full JavaScript flexibility in JSX

Wrap-up

Transitioning from React to Vue has made me a more adaptable developer. I’ve learned that frameworks are simply tools for expressing UI logic — what matters most is how they shape collaboration, performance, and developer happiness. Vue’s reactivity model, single-file components, and elegant Composition API have completely changed how I think about building for the web

For anyone coming from React, Vue is not just a change — it’s a mindset shift. And once it clicks, it’s incredibly fun