Blog>
Snippets

Reactivity with the Options API

Compare the reactivity systems between the Composition API and Options API by creating the same reactive data structure with both in Vue.js 3.
<div id="optionsApiApp">
  <h1>{{ message }}</h1>
  <button @click="incrementCounter">Increment</button>
  <p>Counter: {{ counter }}</p>
</div>
This is the HTML markup for the Vue Options API example. It binds message and counter properties and listens to a click event on the button to call the incrementCounter method.
new Vue({
  el: '#optionsApiApp',
  data() {
    return {
      message: 'Options API Example',
      counter: 0
    };
  },
  methods: {
    incrementCounter() {
      this.counter++;
    }
  }
});
This is the Vue instance using Options API. It declares a data object with a message and a counter, and a method to increment the counter.
<div id="compositionApiApp">
  <h1>{{ state.message }}</h1>
  <button @click="incrementCounter">Increment</button>
  <p>Counter: {{ state.counter }}</p>
</div>
This is the HTML markup for the Vue Composition API example. It binds the message and counter properties within a reactive state object and listens to a click event on the button to call the incrementCounter function.
const { createApp, reactive } = Vue;

const app = createApp({
  setup() {
    const state = reactive({
      message: 'Composition API Example',
      counter: 0
    });

    function incrementCounter() {
      state.counter++;
    }

    return { state, incrementCounter };
  }
});

app.mount('#compositionApiApp');
This is the Vue instance using Composition API. It utilizes the setup function to create a reactive state and a function to increment the counter. Then it returns an object exposing the state and the incrementCounter function to the template.
/* CSS styling common to both examples */
#optionsApiApp, #compositionApiApp {
  text-align: center;
  margin-top: 50px;
}

button {
  margin-top: 20px;
  cursor: pointer;
}
Common CSS styles for both examples. Aligns text to the center and styles the button.