{"id":235,"date":"2022-05-17T09:18:23","date_gmt":"2022-05-17T09:18:23","guid":{"rendered":"https:\/\/felixaugenstein.com\/blog\/?p=235"},"modified":"2022-05-17T09:20:11","modified_gmt":"2022-05-17T09:20:11","slug":"vue-3-components-in-two-different-api-styles-options-api-and-composition-api","status":"publish","type":"post","link":"https:\/\/felixaugenstein.com\/blog\/vue-3-components-in-two-different-api-styles-options-api-and-composition-api\/","title":{"rendered":"Vue 3 components in two different API styles: Options API and Composition API"},"content":{"rendered":"\n<p>In a previous tutorial the process of setting up a new Vue 3 project has been explained. If you first want to set up a Vue 3 app to then work with the Options or Composition API, please take a look at <a href=\"https:\/\/felixaugenstein.com\/blog\/create-a-vue-js-3-project-either-with-the-vue-cli-or-with-vite\/\" target=\"_blank\" rel=\"noreferrer noopener\">this tutorial<\/a>.<\/p>\n\n\n\n<p>Now let\u2019s take a look at how the components work.<\/p>\n\n\n\n<p>With Vue 3 the Composition API has been introduced. In comparison to the Options API, we are now able to organize our code by feature using the Composition API rather than only being able to separate it by data, computed, etc.<\/p>\n\n\n\n<p>In our previously created app, let&#8217;s open the <code>HelloWorld.vue<\/code> component, you can find it under <code>src\/components\/HelloWorld.vue<\/code> and built an increment function \/ method with both the Options and Composition API.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Options API<\/h2>\n\n\n\n<p>Using the Options API, we can define a component&#8217;s logic using an object of options such as&nbsp;<code>data<\/code>,&nbsp;<code>methods<\/code>, and&nbsp;<code>mounted<\/code>. Properties defined by options are exposed on&nbsp;<code>this<\/code>&nbsp;inside our functions, which points to the component instance. Now let&#8217;s change the <code>&lt;template&gt;<\/code> and <code>&lt;script&gt;<\/code> tags of our <code>HelloWorld.vue<\/code> component.<\/p>\n\n\n\n<p>Change the <code>&lt;template&gt;<\/code> tag to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;template&gt;\n  &lt;div class=\"hello\"&gt;\n    &lt;button @click=\"increment\"&gt;Count is: {{ count }}&lt;\/button&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;<\/code><\/pre>\n\n\n\n<p>Change the <code>&lt;script&gt;<\/code> tag to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script&gt;\nexport default {\n  name: 'HelloWorld',\n  data() {\n    return {\n      count: 0\n    }\n  },\n\n  \/\/ Methods are functions that mutate state and trigger updates.\n  \/\/ They can be bound as event listeners in templates.\n  methods: {\n    increment() {\n      this.count++\n    }\n  },\n\n  \/\/ Lifecycle hooks are called at different stages\n  \/\/ of a component's lifecycle.\n  \/\/ This function will be called when the component is mounted.\n  mounted() {\n    console.log(`The initial count is ${this.count}.`)\n  }\n}\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>If you start the Vue app you should see a count button, that triggers our increment function \/ method.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Composition API<\/h2>\n\n\n\n<p>Now let&#8217;s change the <code>&lt;script&gt;<\/code> tag of our <code>HelloWorld.vue<\/code> component again, to use the Composition API this time. We can leave the <code>&lt;template&gt;<\/code> tag as it is.<\/p>\n\n\n\n<p>Using the Composition API, we can define a component&#8217;s logic using imported API functions. The Composition API is typically used with a&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/vuejs.org\/api\/sfc-script-setup.html\" target=\"_blank\"><code>&lt;script setup&gt;<\/code><\/a> inside Single File Components (SFCs). The&nbsp;<code>setup<\/code>&nbsp;attribute makes Vue perform compile-time transforms that have a few advantages over using just the <code>&lt;script&gt;<\/code> tag like less boilerplate, better runtime performance or imports and top-level variables \/ functions declared in&nbsp;<code>&lt;script setup&gt;<\/code>&nbsp;being directly usable in the template.<\/p>\n\n\n\n<p>Here is the same component, with the exact same template, but using Composition API and&nbsp;<code>&lt;script setup&gt;<\/code>&nbsp;instead:<\/p>\n\n\n\n<p>Replace the <code>&lt;script&gt;<\/code> tag with the <code>&lt;script setup&gt;<\/code> tag:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script setup&gt;\nimport { ref, onMounted } from 'vue'\n\n\/\/ reactive state\nconst count = ref(0)\n\n\/\/ functions that mutate state and trigger updates\nfunction increment() {\n  count.value++\n  console.log(`Now the count is ${count.value}.`)\n}\n\n\/\/ lifecycle hooks\nonMounted(() =&gt; {\n  console.log(`The initial count is ${count.value}.`)\n})\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>If you start the Vue app again you should see the same count button, that triggers our increment function.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Options vs. Composition API &#8211; which one to choose?<\/h2>\n\n\n\n<p>In general both the Options and the Composition API can be used equally to develop applications. The underlying system for both is the same, as the Options API is implemented on top of the Composition API. <\/p>\n\n\n\n<p>The Options API is centered around the concept of a &#8220;component instance&#8221; (<code>this<\/code>&nbsp;as seen in the example), which is ideal for users coming from object-oriented programming (OOP). It is also more beginner-friendly by abstracting away the reactivity details and enforcing code organization via option groups, like <code>data<\/code>,&nbsp;<code>methods<\/code>, and&nbsp;<code>mounted<\/code><\/p>\n\n\n\n<p>The Composition API is centered around declaring reactive state variables, such as <code>ref()<\/code>&nbsp;and&nbsp;<code>reactive()<\/code>, and composing state from multiple functions. It is more of a free-form, and requires more knowledge about how reactivity works, in return it is more flexible.<\/p>\n\n\n\n<p>For more information there is a\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/vuejs.org\/guide\/extras\/composition-api-faq.html\" target=\"_blank\">Composition API FAQ available on vuejs.org<\/a> and another helpful resource is <a rel=\"noreferrer noopener\" href=\"https:\/\/learnvue.co\/\" target=\"_blank\">https:\/\/learnvue.co\/<\/a>.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a previous tutorial the process of setting up a new Vue 3 project has been explained. If you first want to set up a Vue 3 app to then work with the Options or Composition API, please take a look at this tutorial. Now let\u2019s take a look at [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":239,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28,30,46],"tags":[],"class_list":["post-235","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application","category-node-js","category-vue-js"],"_links":{"self":[{"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/posts\/235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/comments?post=235"}],"version-history":[{"count":7,"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/posts\/235\/revisions"}],"predecessor-version":[{"id":245,"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/posts\/235\/revisions\/245"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/media\/239"}],"wp:attachment":[{"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/media?parent=235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/categories?post=235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/felixaugenstein.com\/blog\/wp-json\/wp\/v2\/tags?post=235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}