{"id":661,"date":"2022-03-30T09:23:27","date_gmt":"2022-03-30T09:23:27","guid":{"rendered":"http:\/\/shabeebk.com\/blog\/?p=661"},"modified":"2022-04-02T10:36:29","modified_gmt":"2022-04-02T10:36:29","slug":"vue-3-composition-api-tutorial-with-example-project","status":"publish","type":"post","link":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/","title":{"rendered":"Vue 3 composition API tutorial: with example project"},"content":{"rendered":"\n<p>When Vue 3 was released one of the most exciting features are <code>Composition<strong> <\/strong>API<\/code><strong>&nbsp;<\/strong>. An alternative to Options API. &nbsp;In this article, let&#8217;s take a look at how we can use <code>Composition<strong> <\/strong>API<\/code><strong>&nbsp;<\/strong>in our project<\/p>\n\n\n\n<p>Full source code available in  <a data-type=\"URL\" data-id=\"https:\/\/github.com\/shabeeb\/vue3-composition-api\" href=\"https:\/\/github.com\/shabeeb\/vue3-composition-api\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub repo<\/a><\/p>\n\n\n\n<p>Demo link: <a rel=\"noreferrer noopener\" href=\"https:\/\/vue3-composition-api.pages.dev\/\" target=\"_blank\">https:\/\/vue3-composition-api.pages.dev\/<\/a><\/p>\n\n\n\n<h2>Vue 3 Setup<\/h2>\n\n\n\n<p>Now let\u2019s start by installing Vue CLI globally. If you already have the CLI, make sure your running at least (I am using <code>Vue CLI v5.0.4<\/code>)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install -g vue-cli<\/code><\/pre>\n\n\n\n<p>We\u2019ll use the Vue CLI to build a simple application( I am using <code>vue3-composition-todo<\/code> as project name here )<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vue create <em>vue3-composition-todo<\/em><\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png\"><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/plugins\/jquery-image-lazy-loading\/images\/grey.gif\" data-original=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png\" alt=\"\" class=\"lazy wp-image-665\" width=\"458\" height=\"193\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png 588w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM-300x127.png 300w\" sizes=\"(max-width: 458px) 100vw, 458px\" \/><noscript><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png\" alt=\"\" class=\"wp-image-665\" width=\"458\" height=\"193\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png 588w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM-300x127.png 300w\" sizes=\"(max-width: 458px) 100vw, 458px\" \/><\/noscript><\/a><\/figure>\n\n\n\n<p>Here I am selecting default Vue 3 <\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.35.46-PM.png\"><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/plugins\/jquery-image-lazy-loading\/images\/grey.gif\" data-original=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.35.46-PM.png\" alt=\"\" class=\"lazy wp-image-666\" width=\"511\" height=\"688\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.35.46-PM.png 761w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.35.46-PM-223x300.png 223w\" sizes=\"(max-width: 511px) 100vw, 511px\" \/><noscript><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.35.46-PM.png\" alt=\"\" class=\"wp-image-666\" width=\"511\" height=\"688\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.35.46-PM.png 761w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.35.46-PM-223x300.png 223w\" sizes=\"(max-width: 511px) 100vw, 511px\" \/><\/noscript><\/a><\/figure>\n\n\n\n<p>After installation move into the folder and as shown above <code>cd vue3-composition-todo<\/code> and start-server <code>npm run serve<\/code> . This will start a development server and we can see it on <code>http:\/\/localhost:8080\/<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM.png\"><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/plugins\/jquery-image-lazy-loading\/images\/grey.gif\" data-original=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM.png\" alt=\"\" class=\"lazy wp-image-668\" width=\"510\" height=\"306\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM.png 1024w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM-300x180.png 300w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM-768x462.png 768w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM-788x474.png 788w\" sizes=\"(max-width: 510px) 100vw, 510px\" \/><noscript><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM.png\" alt=\"\" class=\"wp-image-668\" width=\"510\" height=\"306\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM.png 1024w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM-300x180.png 300w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM-768x462.png 768w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.39.43-PM-788x474.png 788w\" sizes=\"(max-width: 510px) 100vw, 510px\" \/><\/noscript><\/a><\/figure>\n\n\n\n<h2>Install plugins<\/h2>\n\n\n\n<p>Let us install Bootstrap for styles in our project <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install bootstrap --save<\/code><\/pre>\n\n\n\n<p>lets import in bootstrap CSS in App.vue (We are using only Bootstrap CSS)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'bootstrap\/dist\/css\/bootstrap.css'<\/code><\/pre>\n\n\n\n<p>Final code in main.js looks like below<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { createApp } from 'vue'\nimport App from '.\/App.vue'\nimport 'bootstrap\/dist\/css\/bootstrap.css'\n\ncreateApp(App).mount('#app')\n<\/code><\/pre>\n\n\n\n<script async=\"\" src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-1812723430816589\" crossorigin=\"anonymous\"><\/script>\n<ins class=\"adsbygoogle\" style=\"display:block; text-align:center;\" data-ad-layout=\"in-article\" data-ad-format=\"fluid\" data-ad-client=\"ca-pub-1812723430816589\" data-ad-slot=\"1589782214\"><\/ins>\n<script>\n     (adsbygoogle = window.adsbygoogle || []).push({});\n<\/script>\n\n\n\n<h2>Create UI for TODO<\/h2>\n\n\n\n<p>First let&#8217;s create a file inside the component <code>TodoList.vue<\/code><\/p>\n\n\n\n<p>Inside template, we can do small HTML to show todo list<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;template&gt;\n  &lt;div class=\"hello\"&gt;\n    &lt;section class=\"vh-100\" style=\"background-color: #eee\"&gt;\n      &lt;div class=\"container py-5 h-100\"&gt;\n        &lt;div class=\"row d-flex justify-content-center align-items-center h-100\"&gt;\n          &lt;div class=\"col col-lg-9 col-xl-7\"&gt;\n            &lt;div class=\"card rounded-3\"&gt;\n              &lt;div class=\"card-body p-4\"&gt;\n                &lt;table class=\"table mb-4\"&gt;\n                  &lt;thead&gt;\n                    &lt;tr&gt;\n                      &lt;th scope=\"col\"&gt;No.&lt;\/th&gt;\n                      &lt;th scope=\"col\"&gt;Todo item&lt;\/th&gt;\n                      &lt;th scope=\"col\"&gt;Status&lt;\/th&gt;\n                      &lt;th scope=\"col\"&gt;Actions&lt;\/th&gt;\n                    &lt;\/tr&gt;\n                  &lt;\/thead&gt;\n\n                  &lt;tbody data-v-3de47834=\"\"&gt;\n                    &lt;tr class=\"\" data-v-3de47834=\"\"&gt;\n                      &lt;th scope=\"row\" data-v-3de47834=\"\"&gt;1&lt;\/th&gt;\n                      &lt;td data-v-3de47834=\"\"&gt;Buy groceries for next week&lt;\/td&gt;\n                      &lt;td data-v-3de47834=\"\"&gt;In progress&lt;\/td&gt;\n                      &lt;td data-v-3de47834=\"\"&gt;\n                        &lt;button\n                          type=\"submit\"\n                          class=\"btn btn-danger\"\n                          data-v-3de47834=\"\"\n                        &gt;\n                          Delete&lt;\/button\n                        &gt;&lt;button\n                          type=\"submit\"\n                          class=\"btn btn-success ms-1\"\n                          data-v-3de47834=\"\"\n                        &gt;\n                          Complete\n                        &lt;\/button&gt;\n                      &lt;\/td&gt;\n                    &lt;\/tr&gt;\n                    &lt;tr class=\"\" data-v-3de47834=\"\"&gt;\n                      &lt;th scope=\"row\" data-v-3de47834=\"\"&gt;2&lt;\/th&gt;\n                      &lt;td data-v-3de47834=\"\"&gt;Pay credit card bill&lt;\/td&gt;\n                      &lt;td data-v-3de47834=\"\"&gt;In progress&lt;\/td&gt;\n                      &lt;td data-v-3de47834=\"\"&gt;\n                        &lt;button\n                          type=\"submit\"\n                          class=\"btn btn-danger\"\n                          data-v-3de47834=\"\"\n                        &gt;\n                          Delete&lt;\/button\n                        &gt;&lt;button\n                          type=\"submit\"\n                          class=\"btn btn-success ms-1\"\n                          data-v-3de47834=\"\"\n                        &gt;\n                          Complete\n                        &lt;\/button&gt;\n                      &lt;\/td&gt;\n                    &lt;\/tr&gt;\n                  &lt;\/tbody&gt;\n                &lt;\/table&gt;\n              &lt;\/div&gt;\n            &lt;\/div&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/section&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;\n\n&lt;script&gt;\n\n&lt;\/script&gt;\n\n&lt;!-- Add \"scoped\" attribute to limit CSS to this component only --&gt;\n&lt;style scoped&gt;\nh3 {\n  margin: 40px 0 0;\n}\nul {\n  list-style-type: none;\n  padding: 0;\n}\nli {\n  display: inline-block;\n  margin: 0 10px;\n}\na {\n  color: #37dd92;\n}\na.link {\n  color: #3771dd;\n}\n.stricked {\n  text-decoration: line-through;\n}\n&lt;\/style&gt;\n<\/code><\/pre>\n\n\n\n<h2>Create composable function <\/h2>\n\n\n\n<p>Now we can create a new folder <code>composable<\/code> inside <code>src<\/code> (we can use clean code and write in separate <code>composable function <\/code>)<\/p>\n\n\n\n<p>In <code>composible\/useTodoList.js<\/code> we can add some basic <code>TodosList<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { reactive } from \"vue\";\nfunction useTodoList() {\n  let state = reactive({\n \n    todos: &#91;\n      {\n        id: 1,\n        title: \"Buy groceries for next week\",\n        completed: false,\n      },\n      {\n        id: 2,\n        title: \"Pay credit card bill \",\n        completed: false,\n      },\n    ],\n  });\n\n  \n  return {\n    state,\n  };\n}\n\nexport default useTodoList<\/code><\/pre>\n\n\n\n<p>Now we can import <code>useTodoList<\/code> in <code>TodoList.vue<\/code> and tweak some code<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;template&gt;\n ...\n\n                  &lt;tbody&gt;\n                    &lt;tr\n                      v-for=\"(todo, idx) in state.todos\"\n                      :key=\"todo.id\"\n                      :class=\"todo.completed &amp;&amp; 'stricked'\"\n                    &gt;\n                      &lt;th scope=\"row\"&gt;{{ idx + 1 }}&lt;\/th&gt;\n                      &lt;td&gt;{{ todo.title }}&lt;\/td&gt;\n                      &lt;td&gt;\n                        {{ todo.completed ? \"Completed\" : \"In progress\" }}\n                      &lt;\/td&gt;\n                      &lt;td&gt;\n                        &lt;button\n                          type=\"submit\"\n                          class=\"btn btn-danger\"\n                          @click=\"removeItem(todo)\"\n                        &gt;\n                          Delete\n                        &lt;\/button&gt;\n                        &lt;button\n                          type=\"submit\"\n                          class=\"btn btn-success ms-1\"\n                          @click=\"toggleCompleted(todo)\"\n                        &gt;\n                          {{ todo.completed ? \"Re-open\" : \"Complete\" }}\n                        &lt;\/button&gt;\n                      &lt;\/td&gt;\n                    &lt;\/tr&gt;\n                  &lt;\/tbody&gt;\n             ...\n&lt;\/template&gt;\n\n&lt;script&gt;\nimport useTodoList from \"@\/composable\/useTodoList\";\nexport default {\n  setup() {\n    const { state } = useTodoList();\n    return {\n      state,\n    };\n  },\n};\n&lt;\/script&gt;\n...\n<\/code><\/pre>\n\n\n\n<p>Let us try to run the server <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run serve<\/code><\/pre>\n\n\n\n<p>Access <code>http:\/\/localhost:8080\/<\/code> and we can see our code is running \ud83d\ude42<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM.png\"><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/plugins\/jquery-image-lazy-loading\/images\/grey.gif\" data-original=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM.png\" alt=\"\" class=\"lazy wp-image-670\" width=\"611\" height=\"219\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM.png 1024w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM-300x108.png 300w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM-768x275.png 768w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM-788x282.png 788w\" sizes=\"(max-width: 611px) 100vw, 611px\" \/><noscript><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM.png\" alt=\"\" class=\"wp-image-670\" width=\"611\" height=\"219\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM.png 1024w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM-300x108.png 300w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM-768x275.png 768w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.24.06-PM-788x282.png 788w\" sizes=\"(max-width: 611px) 100vw, 611px\" \/><\/noscript><\/a><\/figure>\n\n\n\n<h2>Add todo<\/h2>\n\n\n\n<p>Let us add some input fields to add a todo to list<\/p>\n\n\n\n<p>in <code>TodoList.vue<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;form\n                  class=\"row row-cols-lg-auto g-3 justify-content-center align-items-center mb-4 pb-2\"\n                  @submit.prevent=\"addToDo\"\n                &gt;\n                  &lt;div class=\"col-12\"&gt;\n                    &lt;div class=\"form-outline\"&gt;\n                      &lt;input\n                        type=\"text\"\n                        id=\"form1\"\n                        v-model=\"state.newTodo\"\n                        class=\"form-control\"\n                        placeholder=\"Enter a task here\"\n                      \/&gt;\n                    &lt;\/div&gt;\n                  &lt;\/div&gt;\n\n                  &lt;div class=\"col-12\"&gt;\n                    &lt;button\n                      type=\"button\"\n                      class=\"btn btn-primary\"\n                      @click=\"addToDo\"\n                    &gt;\n                      Save\n                    &lt;\/button&gt;\n                  &lt;\/div&gt;\n                &lt;\/form&gt;\n...\n&lt;script&gt;\n...\n  setup() {\n    const { state, addToDo } =\n      useTodoList();\n    return {\n      state,\n      addToDo,\n      \n    };\n};\n...\n&lt;\/script&gt;\n<\/code><\/pre>\n\n\n\n<p>In <code>useTodoList<\/code>.js we can add new methode and export <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...  \nfunction addToDo(e) {\n    e.preventDefault();\n    state.todos.push({\n      id: state.todos.length + 1,\n      title: state.newTodo,\n      completed: false,\n    });\n    state.newTodo = \"\";\n  }\n...\nreturn {\n    state,\n    addToDo, \n  };\n...<\/code><\/pre>\n\n\n\n<p>We have a save function now, after typing on click of saving we call addToDo and push data into our todos object. and the table will re-render and show a new to-do items.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM.png\"><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/plugins\/jquery-image-lazy-loading\/images\/grey.gif\" data-original=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM.png\" alt=\"\" class=\"lazy wp-image-671\" width=\"628\" height=\"325\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM.png 1024w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM-300x156.png 300w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM-768x398.png 768w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM-788x409.png 788w\" sizes=\"(max-width: 628px) 100vw, 628px\" \/><noscript><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM.png\" alt=\"\" class=\"wp-image-671\" width=\"628\" height=\"325\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM.png 1024w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM-300x156.png 300w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM-768x398.png 768w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.35.23-PM-788x409.png 788w\" sizes=\"(max-width: 628px) 100vw, 628px\" \/><\/noscript><\/a><\/figure>\n\n\n\n<p>The same way we can add more functionality like <code>removeItem<\/code> (delete a todo item on click of delete button), <code>toggleCompleted<\/code> (toggle as completed and in progress) and <code>addTodoForme<\/code> (adding sample data )<\/p>\n\n\n\n<h2>Final code <\/h2>\n\n\n\n<p>final code in component\/TodoList.vue<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;template&gt;\n  &lt;div class=\"hello\"&gt;\n    &lt;section class=\"vh-100\" style=\"background-color: #eee\"&gt;\n      &lt;div class=\"container py-5 h-100\"&gt;\n        &lt;div class=\"row d-flex justify-content-center align-items-center h-100\"&gt;\n          &lt;div class=\"col col-lg-9 col-xl-7\"&gt;\n            &lt;div class=\"card rounded-3\"&gt;\n              &lt;div class=\"card-body p-4\"&gt;\n                &lt;div&gt;\n                  &lt;a\n                    href=\"http:\/\/shabeebk.com\/blog\/simple-vue-composition-api-example-with-todo-app\/\"\n                    target=\"_sb\"\n                    class=\"link\"\n                    &gt;Read Full Blog\n                  &lt;\/a&gt;\n                &lt;\/div&gt;\n                &lt;h4 class=\"text-center my-3 pb-3\"&gt;\n                  Vue 3 with composition-api To Do App\n                &lt;\/h4&gt;\n\n                &lt;form\n                  class=\"row row-cols-lg-auto g-3 justify-content-center align-items-center mb-4 pb-2\"\n                  @submit.prevent=\"addToDo\"\n                &gt;\n                  &lt;div class=\"col-12\"&gt;\n                    &lt;div class=\"form-outline\"&gt;\n                      &lt;input\n                        type=\"text\"\n                        id=\"form1\"\n                        v-model=\"state.newTodo\"\n                        class=\"form-control\"\n                        placeholder=\"Enter a task here\"\n                      \/&gt;\n                    &lt;\/div&gt;\n                  &lt;\/div&gt;\n\n                  &lt;div class=\"col-12\"&gt;\n                    &lt;button\n                      type=\"button\"\n                      class=\"btn btn-primary\"\n                      @click=\"addToDo\"\n                    &gt;\n                      Save\n                    &lt;\/button&gt;\n                  &lt;\/div&gt;\n\n                  &lt;div class=\"col-12\"&gt;\n                    &lt;button\n                      type=\"button\"\n                      class=\"btn btn-warning\"\n                      @click=\"addTodoForme\"\n                    &gt;\n                      Add sample\n                    &lt;\/button&gt;\n                  &lt;\/div&gt;\n                &lt;\/form&gt;\n\n                &lt;table class=\"table mb-4\"&gt;\n                  &lt;thead&gt;\n                    &lt;tr&gt;\n                      &lt;th scope=\"col\"&gt;No.&lt;\/th&gt;\n                      &lt;th scope=\"col\"&gt;Todo item&lt;\/th&gt;\n                      &lt;th scope=\"col\"&gt;Status&lt;\/th&gt;\n                      &lt;th scope=\"col\"&gt;Actions&lt;\/th&gt;\n                    &lt;\/tr&gt;\n                  &lt;\/thead&gt;\n\n                  &lt;tbody&gt;\n                    &lt;tr\n                      v-for=\"(todo, idx) in state.todos\"\n                      :key=\"todo.id\"\n                      :class=\"todo.completed &amp;&amp; 'stricked'\"\n                    &gt;\n                      &lt;th scope=\"row\"&gt;{{ idx + 1 }}&lt;\/th&gt;\n                      &lt;td&gt;{{ todo.title }}&lt;\/td&gt;\n                      &lt;td&gt;\n                        {{ todo.completed ? \"Completed\" : \"In progress\" }}\n                      &lt;\/td&gt;\n                      &lt;td&gt;\n                        &lt;button\n                          type=\"submit\"\n                          class=\"btn btn-danger\"\n                          @click=\"removeItem(todo)\"\n                        &gt;\n                          Delete\n                        &lt;\/button&gt;\n                        &lt;button\n                          type=\"submit\"\n                          class=\"btn btn-success ms-1\"\n                          @click=\"toggleCompleted(todo)\"\n                        &gt;\n                          {{ todo.completed ? \"Re-open\" : \"Complete\" }}\n                        &lt;\/button&gt;\n                      &lt;\/td&gt;\n                    &lt;\/tr&gt;\n                  &lt;\/tbody&gt;\n                &lt;\/table&gt;\n              &lt;\/div&gt;\n            &lt;\/div&gt;\n          &lt;\/div&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    &lt;\/section&gt;\n  &lt;\/div&gt;\n&lt;\/template&gt;\n\n&lt;script&gt;\nimport useTodoList from \"@\/composable\/useTodoList\";\nexport default {\n  setup() {\n    const { state, addToDo, toggleCompleted, removeItem, addTodoForme } =\n      useTodoList();\n    return {\n      state,\n      addToDo,\n      toggleCompleted,\n      removeItem,\n      addTodoForme,\n    };\n  },\n};\n&lt;\/script&gt;\n\n&lt;!-- Add \"scoped\" attribute to limit CSS to this component only --&gt;\n&lt;style scoped&gt;\nh3 {\n  margin: 40px 0 0;\n}\nul {\n  list-style-type: none;\n  padding: 0;\n}\nli {\n  display: inline-block;\n  margin: 0 10px;\n}\na {\n  color: #37dd92;\n}\na.link {\n  color: #3771dd;\n}\n.stricked {\n  text-decoration: line-through;\n}\n&lt;\/style&gt;\n<\/code><\/pre>\n\n\n\n<p>In <code>composable\/useTodoList.js<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { reactive } from \"vue\";\nfunction useTodoList() {\n  let state = reactive({\n    newTodo: \"\",\n    todos: &#91;\n      {\n        id: 1,\n        title: \"Buy groceries for next week\",\n        completed: false,\n      },\n      {\n        id: 2,\n        title: \"Pay credit card bill \",\n        completed: false,\n      },\n    ],\n  });\n\n  function addToDo(e) {\n    e.preventDefault();\n    state.todos.push({\n      id: state.todos.length + 1,\n      title: state.newTodo,\n      completed: false,\n    });\n    state.newTodo = \"\";\n  }\n\n  function toggleCompleted(item) {\n    item.completed = !item.completed;\n  }\n  function removeItem(item) {\n    state.todos = state.todos.filter((newItem) =&gt; newItem.id !== item.id);\n  }\n  function addTodoForme(e) {\n    e.preventDefault();\n    const text = `New to do list item with id ${state.todos.length + 1}`;\n    state.todos.push({\n      id: state.todos.length + 1,\n      title: text,\n      completed: false,\n    });\n  }\n  return {\n    state,\n    addToDo,\n    toggleCompleted,\n    removeItem,\n    addTodoForme,\n  };\n}\n\nexport default useTodoList;\n<\/code><\/pre>\n\n\n\n<p>And final output <\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM.png\"><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/plugins\/jquery-image-lazy-loading\/images\/grey.gif\" data-original=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM.png\" alt=\"\" class=\"lazy wp-image-672\" width=\"551\" height=\"299\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM.png 1024w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM-300x163.png 300w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM-768x418.png 768w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM-788x429.png 788w\" sizes=\"(max-width: 551px) 100vw, 551px\" \/><noscript><img loading=\"lazy\" src=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM.png\" alt=\"\" class=\"wp-image-672\" width=\"551\" height=\"299\" srcset=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM.png 1024w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM-300x163.png 300w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM-768x418.png 768w, http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-2.42.16-PM-788x429.png 788w\" sizes=\"(max-width: 551px) 100vw, 551px\" \/><\/noscript><\/a><\/figure>\n\n\n\n<h2>Conclusion<\/h2>\n\n\n\n<p>Finally, we\u2019ve built our app with Vue 3 Composition API.<br>I hope you learned a few things about Vue 3 and Composition API, Let me know if you have any comments<\/p>\n\n\n\n<p>You can download the full source code from my <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/shabeeb\/vue3-composition-api\" data-type=\"URL\" data-id=\"https:\/\/github.com\/shabeeb\/vue3-composition-api\" target=\"_blank\">GitHub repo<\/a><\/p>\n\n\n\n<p>Demo link: <a rel=\"noreferrer noopener\" href=\"https:\/\/vue3-composition-api.pages.dev\/\" target=\"_blank\">https:\/\/vue3-composition-api.pages.dev\/<\/a><\/p>\n\n\n\n<script async=\"\" src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-1812723430816589\" crossorigin=\"anonymous\"><\/script>\n<ins class=\"adsbygoogle\" style=\"display:block; text-align:center;\" data-ad-layout=\"in-article\" data-ad-format=\"fluid\" data-ad-client=\"ca-pub-1812723430816589\" data-ad-slot=\"1589782214\"><\/ins>\n<script>\n     (adsbygoogle = window.adsbygoogle || []).push({});\n<\/script>\n<div class=\"pvc_clear\"><\/div><p class=\"pvc_stats all \" data-element-id=\"661\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> &nbsp;2,224&nbsp;total views, &nbsp;1&nbsp;views today<\/p><div class=\"pvc_clear\"><\/div>","protected":false},"excerpt":{"rendered":"<p>When Vue 3 was released one of the most exciting features are Composition API&nbsp;. An alternative to Options API. &nbsp;In this article, let&#8217;s take a look at how we can use Composition API&nbsp;in our project Full source code available in GitHub repo Demo link: https:\/\/vue3-composition-api.pages.dev\/ Vue 3 Setup Now let\u2019s start by installing Vue CLI [&hellip;]<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p class=\"pvc_stats all \" data-element-id=\"661\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> &nbsp;2,224&nbsp;total views, &nbsp;1&nbsp;views today<\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":""},"categories":[4,1,62,79],"tags":[71,77,68,72,75,74,66],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v18.4.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Vue 3 composition API tutorial: with example project - shabeeb Blog<\/title>\n<meta name=\"description\" content=\"Vue 3 Composition API overview Vue 3 Composition API vs options API, and Vue composition API ref, Reactive, data, setup api- lifecycle hooks\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Vue 3 composition API tutorial: with example project - shabeeb Blog\" \/>\n<meta property=\"og:description\" content=\"A developer blog\" \/>\n<meta property=\"og:url\" content=\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/\" \/>\n<meta property=\"og:site_name\" content=\"shabeeb Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-30T09:23:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-04-02T10:36:29+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"shabeeb\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"http:\/\/shabeebk.com\/blog\/#website\",\"url\":\"http:\/\/shabeebk.com\/blog\/\",\"name\":\"shabeeb Blog\",\"description\":\"A developer blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/shabeebk.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png\",\"contentUrl\":\"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png\",\"width\":588,\"height\":248},{\"@type\":\"WebPage\",\"@id\":\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#webpage\",\"url\":\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/\",\"name\":\"Vue 3 composition API tutorial: with example project - shabeeb Blog\",\"isPartOf\":{\"@id\":\"http:\/\/shabeebk.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#primaryimage\"},\"datePublished\":\"2022-03-30T09:23:27+00:00\",\"dateModified\":\"2022-04-02T10:36:29+00:00\",\"author\":{\"@id\":\"http:\/\/shabeebk.com\/blog\/#\/schema\/person\/71832abe654179971635c65c09bceb29\"},\"description\":\"Vue 3 Composition API overview Vue 3 Composition API vs options API, and Vue composition API ref, Reactive, data, setup api- lifecycle hooks\",\"breadcrumb\":{\"@id\":\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"http:\/\/shabeebk.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Vue 3 composition API tutorial: with example project\"}]},{\"@type\":\"Person\",\"@id\":\"http:\/\/shabeebk.com\/blog\/#\/schema\/person\/71832abe654179971635c65c09bceb29\",\"name\":\"shabeeb\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"http:\/\/shabeebk.com\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/0.gravatar.com\/avatar\/9998389cc76a77663881c48f7d4cbba0?s=96&d=mm&r=g\",\"contentUrl\":\"http:\/\/0.gravatar.com\/avatar\/9998389cc76a77663881c48f7d4cbba0?s=96&d=mm&r=g\",\"caption\":\"shabeeb\"},\"description\":\"Developer,Entrepreneur, software engineer more than that a human being\",\"sameAs\":[\"http:\/\/shabeebk.com\/blog\"],\"url\":\"http:\/\/shabeebk.com\/blog\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Vue 3 composition API tutorial: with example project - shabeeb Blog","description":"Vue 3 Composition API overview Vue 3 Composition API vs options API, and Vue composition API ref, Reactive, data, setup api- lifecycle hooks","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/","og_locale":"en_US","og_type":"article","og_title":"Vue 3 composition API tutorial: with example project - shabeeb Blog","og_description":"A developer blog","og_url":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/","og_site_name":"shabeeb Blog","article_published_time":"2022-03-30T09:23:27+00:00","article_modified_time":"2022-04-02T10:36:29+00:00","og_image":[{"url":"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png"}],"twitter_misc":{"Written by":"shabeeb","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebSite","@id":"http:\/\/shabeebk.com\/blog\/#website","url":"http:\/\/shabeebk.com\/blog\/","name":"shabeeb Blog","description":"A developer blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/shabeebk.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"ImageObject","@id":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#primaryimage","inLanguage":"en-US","url":"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png","contentUrl":"http:\/\/shabeebk.com\/blog\/wp-content\/uploads\/2022\/03\/Screen-Shot-2022-03-30-at-12.34.36-PM.png","width":588,"height":248},{"@type":"WebPage","@id":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#webpage","url":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/","name":"Vue 3 composition API tutorial: with example project - shabeeb Blog","isPartOf":{"@id":"http:\/\/shabeebk.com\/blog\/#website"},"primaryImageOfPage":{"@id":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#primaryimage"},"datePublished":"2022-03-30T09:23:27+00:00","dateModified":"2022-04-02T10:36:29+00:00","author":{"@id":"http:\/\/shabeebk.com\/blog\/#\/schema\/person\/71832abe654179971635c65c09bceb29"},"description":"Vue 3 Composition API overview Vue 3 Composition API vs options API, and Vue composition API ref, Reactive, data, setup api- lifecycle hooks","breadcrumb":{"@id":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/shabeebk.com\/blog\/vue-3-composition-api-tutorial-with-example-project\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http:\/\/shabeebk.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Vue 3 composition API tutorial: with example project"}]},{"@type":"Person","@id":"http:\/\/shabeebk.com\/blog\/#\/schema\/person\/71832abe654179971635c65c09bceb29","name":"shabeeb","image":{"@type":"ImageObject","@id":"http:\/\/shabeebk.com\/blog\/#personlogo","inLanguage":"en-US","url":"http:\/\/0.gravatar.com\/avatar\/9998389cc76a77663881c48f7d4cbba0?s=96&d=mm&r=g","contentUrl":"http:\/\/0.gravatar.com\/avatar\/9998389cc76a77663881c48f7d4cbba0?s=96&d=mm&r=g","caption":"shabeeb"},"description":"Developer,Entrepreneur, software engineer more than that a human being","sameAs":["http:\/\/shabeebk.com\/blog"],"url":"http:\/\/shabeebk.com\/blog\/author\/admin\/"}]}},"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/posts\/661"}],"collection":[{"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/comments?post=661"}],"version-history":[{"count":9,"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/posts\/661\/revisions"}],"predecessor-version":[{"id":719,"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/posts\/661\/revisions\/719"}],"wp:attachment":[{"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/media?parent=661"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/categories?post=661"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/shabeebk.com\/blog\/wp-json\/wp\/v2\/tags?post=661"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}