{"_path":"/posts/scale-your-vue-components","_draft":false,"_partial":false,"_empty":false,"title":"Scaling Your Vue Components for Mid-Large Size Apps","description":"Working on a mid-large size app usually means hundreds of components. How do you make sure these components will scale?","publishedAt":"2021-01-12","image":"https://harlanzw.com/social/scale-your-vue-components.png","tags":["vue"],"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"One of the key pieces in scaling your Vue app is having good component architecture."}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"How are components named?"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"What folder hierarchy should you use?"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"How is component code scoped?"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The cost of not having clear answers to these simple questions increases as your app grows."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"My previous role was the tech lead at a startup. Growing pains were frequent with pivots, design changes and new features. All pushing our total component count up."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"My below suggestions are what I came up with to solve "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"our"}]},{"type":"text","value":" scaling issues. Your project will have its own requirements."}]},{"type":"element","tag":"h2","props":{"id":"100-component-club"},"children":[{"type":"text","value":"100+ component club"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's assume once you hit 100+ components, then you are a mid-size app and you will be feeling your own growing pains."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Are you in the club? Run the following in your component folder:"}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"shell","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"# cd app/components\nCOMPONENTS=$(ls -lR **/*.vue | wc -l) && echo -e \"You have ${COMPONENTS} components.\"\n","language":"shell"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# cd app/components"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"COMPONENTS="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"$("}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"ls -lR "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"**"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"*"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":".vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":" wc -l"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":")"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"&&"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" -e "}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"You have "}]},{"type":"element","tag":"span","props":{"style":{"color":"#BD93F9"}},"children":[{"type":"text","value":"${COMPONENTS}"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":" components."}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"problems-you-may-have"},"children":[{"type":"text","value":"Problems you may have"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Difficult to remember which component to use where"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Code is being repeated"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Monolithic components"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"New components are being built instead of leveraging existing ones"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Inconsistent emits and props between components with the same functionality"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Technical debt is being ignored because it is too painful"}]}]},{"type":"element","tag":"h2","props":{"id":"solving-component-scaling-with-rules"},"children":[{"type":"text","value":"Solving component scaling with rules"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Good code adheres to a set of rules. You either follow existing rules (syntax and conventions) or create\nnew ones and make sure others follow them (documentation and code reviews)."}]},{"type":"element","tag":"h3","props":{"id":"rule-0-have-good-dev-processes"},"children":[{"type":"text","value":"Rule 0. Have good dev processes"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There is no substitute for a good development process. You need to be following best continuous delivery, documentation and communication practices.\nThe rest of the rules will not help you if you are not functioning like a well-oiled machine."}]},{"type":"element","tag":"h3","props":{"id":"rule-1-know-the-style-guide"},"children":[{"type":"text","value":"Rule 1. Know the style guide"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You should be familiar with the official "},{"type":"element","tag":"a","props":{"href":"https://v3.vuejs.org/style-guide/","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Vue.js Style Guide"}]},{"type":"text","value":".\nIt gives you clear, concise instructions on what you should and shouldn't do.\nYou should set up "},{"type":"element","tag":"a","props":{"href":"https://eslint.vuejs.org/","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"eslint-plugin-vue"}]},{"type":"text","value":" with the recommended rules."}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"js","class":"code-block code-block--with-filename"},"children":[{"type":"element","tag":"span","props":{"class":"code-block__filename"},"children":[{"type":"text","value":".eslintrc.js"}]},{"type":"element","tag":"code","props":{"code":"module.exports = {\n  extends: [\n    // ...\n    'plugin:vue/vue3-recommended',\n    // 'plugin:vue/recommended' // Use this if you are using Vue.js 2.x.\n  ],\n}\n","filename":".eslintrc.js","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"module"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"exports"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  extends"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" ["}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"// ..."}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    "}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"plugin:vue/vue3-recommended"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"// 'plugin:vue/recommended' // Use this if you are using Vue.js 2.x."}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  ],"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"}"}]}]}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"rule-2-use-a-component-naming-convention"},"children":[{"type":"text","value":"Rule 2. Use a component naming convention"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The bane of developers lives: how to name something."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You can address that by having an easy-to-follow convention on how to name a component. The convention also tells you where to put the component in your folder hierarchy."}]},{"type":"element","tag":"div","props":{"className":["language-","px-4","py-2","text-white"]},"children":[{"type":"element","tag":"span","props":{"className":["text-yellow-700"]},"children":[{"type":"text","value":"{prefix}"}]},{"type":"text","value":"-"},{"type":"element","tag":"span","props":{"className":["text-blue-700"]},"children":[{"type":"text","value":"{namespace}"}]},{"type":"element","tag":"span","props":{"className":["text-pink-700"]},"children":[{"type":"text","value":"{?-class}"}]}]},{"type":"element","tag":"h4","props":{"id":"prefix"},"children":[{"type":"text","value":"Prefix"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Base components (a.k.a. presentational, dumb, or pure components) that apply app-specific styling and conventions should all begin with a specific prefix, such as Base, App, or V."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A short prefix for "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"all"}]},{"type":"text","value":" your components is preferable to the above."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Using a prefix avoids conflicts with HTML tags and third-party components. It also gives you scoped IDE autocompletion and more reusable components."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Prefixing becomes especially important when working with a component library ("},{"type":"element","tag":"a","props":{"href":"https://vuetifyjs.com/","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Vuetify"}]},{"type":"text","value":", "},{"type":"element","tag":"a","props":{"href":"https://yuche.github.io/vue-strap/","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"VueStrap"}]},{"type":"text","value":", etc) or third-party components\n("},{"type":"element","tag":"a","props":{"href":"https://github.com/algolia/vue-instantsearch","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"algolia"}]},{"type":"text","value":", "},{"type":"element","tag":"a","props":{"href":"https://github.com/xkjyeah/vue-google-maps","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"google maps"}]},{"type":"text","value":", etc)."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You should use something which relates to your app, for example, I use "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"h"}]},{"type":"text","value":" as the prefix because my site is harlanzw.com."}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"vue","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"<template>\n  <p>Please enter your email to subscribe</p>\n  <!-- Vuetify components use a V prefix -->\n  <v-text-field label=\"Your Email\" />\n  <!-- H is the prefix for my apps components -->\n  <h-button>Submit</h-button>\n</template>\n","language":"vue"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"p"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"Please"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"enter"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"your"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"email"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"to"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"subscribe"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"p"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <!-- "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"Vuetify"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"components"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"use"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"V"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"prefix"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" -->"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"v-text-field"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"label"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"Your Email"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <!-- "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"H"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"is"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"the"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"prefix"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"my"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"apps"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"components"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" -->"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-button"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"Submit"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-button"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You can use many prefixes for your components to help you with scoping code."}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"vue","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"<template>\n  <!-- 'the' as a prefix for layout components -->\n  <the-header>\n    <!-- 'v' prefix for vuetify components -->\n    <v-img src=\"logo.png\" />\n    <!-- 'h' prefix for our branded components -->\n    <h-button>Sign In</h-button>\n  </the-header>\n  <main>\n    <the-sidebar />\n    <the-content v-html=\"content\" />\n  </main>\n  <the-footer />\n</template>\n","language":"vue"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <!-- "}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"the"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"prefix"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"layout"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"components"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" -->"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"the-header"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <!-- "}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"v"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"prefix"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"vuetify"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"components"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" -->"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"v-img"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"src"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"logo.png"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <!-- "}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"h"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"prefix"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"our"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"branded"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"components"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" -->"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-button"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"Sign"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"In"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-button"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"the-header"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"main"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"the-sidebar"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"the-content"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"v-html"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"content"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"main"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"the-footer"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]}]}]}]}]},{"type":"element","tag":"h4","props":{"id":"namespace"},"children":[{"type":"text","value":"Namespace"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Child components that are tightly coupled with their parent should include the parent component name as a prefix."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The style guide recommends starting the component name with the parent component. I've found using a "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"namespace"}]},{"type":"text","value":" after the prefix instead is more flexible."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Namespaces avoid conflicts, improve IDE autocompletion and define the scope of the component."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You should map namespaces to a folder, this way you can group components, making them easier to find and use."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"An example of a namespace is "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"Field"}]},{"type":"text","value":", for all our field components (text field, textarea, search, etc.)."}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"shell","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"components/\n|- Field/ # namespace\n|--- HFieldText.vue\n|--- HFieldTextarea.vue\n|--- HFieldSearch.vue\n|--- HFieldAutocomplete.vue\n|--- HFieldCheckbox.vue\n","language":"shell"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"components/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"- Field/ "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# namespace"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HFieldText.vue"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HFieldTextarea.vue"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HFieldSearch.vue"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HFieldAutocomplete.vue"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HFieldCheckbox.vue"}]}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You can then create conventions that components in a namespace should follow. For example these components should all have a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":":value"}]},{"type":"text","value":" prop and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"$emit('input', value)"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h4","props":{"id":"class-optional"},"children":[{"type":"text","value":"Class (optional)"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Component names should start with the highest-level (often most general) words and end with descriptive modifying words."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The final part of the convention is, in fact, the name of the component. Thinking of it as a class name makes the distinction between the namespace easier. You still want to follow the above style guide rule, our class names should be\ngeneral to descriptive."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The class should be optional. Namespaces can provide a default component to reduce the name of common components."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Imagine you have a project with a few buttons. Most of the time you want to use the default button, you shouldn't\nneed to name it "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"HButtonDefault.vue"}]},{"type":"text","value":"."}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"shell","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"components/\n|- Button/ # namespace\n|--- HButton.vue # The namespaces default component \n|--- HButtonCallToAction.vue # A call to action button\n|--- HButtonSubmitForm.vue # A button to submit forms\n","language":"shell"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"components/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"- Button/ "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# namespace"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HButton.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# The namespaces default component "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HButtonCallToAction.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# A call to action button"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HButtonSubmitForm.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# A button to submit forms"}]}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Recommendations on naming the class:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Describe the application function of the component, rather than what it looks like."},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"❌ "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"HButtonRainbowFlashing.vue"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"✅ "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"HButtonCallToAction.vue"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Choose to be verbose if it adds clarity to the scope."},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"❌ "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"HProfileUser.vue"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"✅ "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"HProfileAuthenticatedUsersCard.vue"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Prefer full words over abbreviations. From the "},{"type":"element","tag":"a","props":{"href":"https://v3.vuejs.org/style-guide/#full-word-component-names-strongly-recommended","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"style guide"}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"h3","props":{"id":"rule-3-separate-component-scopes"},"children":[{"type":"text","value":"Rule 3. Separate component scopes"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Defining scopes for how components behave will guide you in staying DRY."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are many ways to set this up. A good starting point is a scope for \"shared\" (a.k.a. base, presentational or dumb) components and \"app\" (a.k.a single-instance)."}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"shell","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"components/\n|- app # Contains application logic\n|- shared # Does not contain application logic\n","language":"shell"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"components/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"- app "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Contains application logic"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"- shared "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Does not contain application logic"}]}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You could also pull out your \"shared\" components into their own npm package."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When creating new components it's natural to couple application logic in. With this setup, you'll think about component scopes more and how code can be re-used."}]},{"type":"element","tag":"Image","props":{"alt":"A decision graph for component folders","height":600,"src":"/blog/component-folder-flow.svg","width":375,"max-height":600,"sizes":"md:375px sm:95vw xs:95vw"},"children":[]},{"type":"element","tag":"h4","props":{"id":"shared-folder---base-components"},"children":[{"type":"text","value":"\"Shared\" Folder - Base Components"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"These components are re-usable and include form inputs, buttons, dialogues and modals. They should never contain application logic or state data."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You should be aiming to build your own \"UI kit\" from these components."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Copy-pasting your shared folder into a new project should work out of the box (assuming you handle dependencies)."}]},{"type":"element","tag":"h4","props":{"id":"app-folder---app-components"},"children":[{"type":"text","value":"\"App\" Folder - App components"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"App components do contain application logic and state data."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you were to copy+paste an app component into a new project, it should not work."}]},{"type":"element","tag":"h2","props":{"id":"example-newsletter-sign-up"},"children":[{"type":"text","value":"Example: Newsletter Sign Up"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This exists as two \"app\" components, they contain logic for validation and posting to an API. They both contain \"shared\" components."}]},{"type":"element","tag":"Image","props":{"alt":"Newsletter component example","height":296,"src":"/blog/newsletter-example.png","width":841,"sizes":"md:841px sm:95vw xs:95vw"},"children":[]},{"type":"element","tag":"CodeBlock","props":{"data-language":"shell","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"components/\n# application component scope\n|- app/ \n|-- Newsletter # namespace\n|--- HNewsletterForm.vue # validates and posts data\n|--- HNewsletterCard.vue # handles successful form post\n# shared component scope\n|- shared/ \n|-- Alert/\n|--- HAlertSuccess.vue\n|-- Button/ \n|--- HButton.vue \n|-- Card/\n|--- HCard.vue\n|-- Form\n|--- HForm.vue\n|-- Field/\n|--- HFieldEmail.vue\n","language":"shell"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"components/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# application component scope"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"- app/ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Newsletter "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# namespace"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HNewsletterForm.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# validates and posts data"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HNewsletterCard.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# handles successful form post"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# shared component scope"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"- shared/ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Alert/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HAlertSuccess.vue"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Button/ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HButton.vue "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Card/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HCard.vue"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Form"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HForm.vue"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Field/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- HFieldEmail.vue"}]}]}]}]}]}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"vue","class":"code-block code-block--with-filename"},"children":[{"type":"element","tag":"span","props":{"class":"code-block__filename"},"children":[{"type":"text","value":"HNewsletterForm.vue"}]},{"type":"element","tag":"code","props":{"code":"<template>\n  <h-form @submit=\"submit\">\n    <h-field-email\n      v-model=\"email\"\n      label=\"Enter your email\"\n    />\n    <h-button type=\"submit\">\n      Subscribe\n    </h-button>\n  </h-form>\n</template>\n","filename":"HNewsletterForm.vue","language":"vue"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-form"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"@"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"submit"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"submit"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-field-email"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"v-model"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"email"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"label"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"Enter your email"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-button"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"type"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"submit"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"Subscribe"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-button"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-form"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]}]}]}]}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"vue","class":"code-block code-block--with-filename"},"children":[{"type":"element","tag":"span","props":{"class":"code-block__filename"},"children":[{"type":"text","value":"HNewsletterCard.vue"}]},{"type":"element","tag":"code","props":{"code":"<template>\n  <h-card>\n    <div class=\"pl-3\">\n      <h2>Keep up to date</h2>\n      <h-newsletter-form\n        v-if=\"!success\"\n        @submit=\"success = true\"\n      />\n      <h-alert-success\n        v-else\n      >\n        Thanks for signing up :)\n      </h-alert-success>\n    </div>\n  </h-card>\n</template>\n","filename":"HNewsletterCard.vue","language":"vue"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-card"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"pl-3"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"2>"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"Keep"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"up"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"to"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"date"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"2>"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-newsletter-form"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"        "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"v-if"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"!"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"success"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"        "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"@"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"submit"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"success "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#BD93F9"}},"children":[{"type":"text","value":"true"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-alert-success"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"        "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"v-else"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      >"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"        "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"Thanks"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"signing"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"up"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" :)"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-alert-success"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"h-card"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"example-forum-thread"},"children":[{"type":"text","value":"Example: Forum Thread"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now imagine you want to build a forum thread page. A user can see comments, upvote comments and post their own comment."}]},{"type":"element","tag":"Image","props":{"alt":"Laravel.io Forum Thread","height":600,"src":"/blog/forum-example.png","width":673,"max-height":600,"sizes":"md:673px sm:95vw xs:95vw"},"children":[]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"F"}]},{"type":"text","value":" as our component prefix, let's look at what you need."}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"shell","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"components/\n# application component scope\n|- app/ \n|-- Thread # namespace\n|--- FThread.vue # Wraps the entire thread\n|--- FThreadPost.vue # A single post / reply\n|--- FThreadFormReply.vue # Form to submit a reply\n|-- Field/\n|--- FFieldComment.vue # Comment box for posts\n|-- Button/\n|--- FButtonUpvote.vue # The thumbs up button\n# shared component scope\n|- shared/ \n|-- Img/\n|--- FImgAvatar.vue # Users photos\n|-- Field/\n|--- FFieldWYSIWYG.vue # Comment box for posts\n|-- Card/\n|--- FCard.vue # Gives posts a 'card' look\n|-- Button/\n|--- FButton.vue # Reply button for the post box\n","language":"shell"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"components/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# application component scope"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"- app/ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Thread "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# namespace"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FThread.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Wraps the entire thread"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FThreadPost.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# A single post / reply"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FThreadFormReply.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Form to submit a reply"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Field/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FFieldComment.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Comment box for posts"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Button/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FButtonUpvote.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# The thumbs up button"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# shared component scope"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"- shared/ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Img/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FImgAvatar.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Users photos"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Field/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FFieldWYSIWYG.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Comment box for posts"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Card/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FCard.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Gives posts a 'card' look"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"-- Button/"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"|"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"--- FButton.vue "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6272A4"}},"children":[{"type":"text","value":"# Reply button for the post box"}]}]}]}]}]}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"vue","class":"code-block code-block--with-filename"},"children":[{"type":"element","tag":"span","props":{"class":"code-block__filename"},"children":[{"type":"text","value":"FThread.vue"}]},{"type":"element","tag":"code","props":{"code":"<template>\n  <f-thread-post\n    v-for=\"posts as post\"\n    :key=\"post.id\"\n    :post=\"post\"\n  />\n  <f-thread-reply @submit=\"addPost\" />\n</template>\n","filename":"FThread.vue","language":"vue"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"f-thread-post"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"v-for"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"posts "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"post"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"    :key="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"post"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"id"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"    :post="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"post"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"  /"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF5555"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"f-thread-reply"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF5555"}},"children":[{"type":"text","value":"@submit=\"addPost\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":">"}]}]}]}]}]}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"vue","class":"code-block code-block--with-filename"},"children":[{"type":"element","tag":"span","props":{"class":"code-block__filename"},"children":[{"type":"text","value":"FThreadPost.vue"}]},{"type":"element","tag":"code","props":{"code":"<template>\n  <f-card>\n    <div class=\"p-3 border-b-2 border-gray-500 flex\">\n      <f-img-avatar :src=\"post.author.avatar\" />\n      <span>{{ post.author.name }}</span>\n      <span>{{ post.publishedAgo }}</span>\n    </div>\n    <div class=\"p-3 border-b-2 border-gray-500 prose\" v-html=\"post.content\" />\n    <div class=\"p-3\">\n      <f-button-upvote\n        :upvotes=\"post.upvotes\"\n        class=\"border-r-2 border-gray-500 pr-3\"\n        @click=\"upvote\"\n      />\n    </div>\n  </f-card>\n</template>\n","filename":"FThreadPost.vue","language":"vue"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"f-card"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"p-3 border-b-2 border-gray-500 flex"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"f-img-avatar"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"src"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"post.author.avatar"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"span"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">{{ "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"post"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"author"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"name"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" }}</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"span"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"span"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">{{ "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"post"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"publishedAgo"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" }}</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"span"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"p-3 border-b-2 border-gray-500 prose"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"v-html"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"post.content"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"p-3"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"f-button-upvote"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"        "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"upvotes"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"post.upvotes"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"        "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"border-r-2 border-gray-500 pr-3"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"        "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"@"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"click"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"upvote"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"f-card"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]}]}]}]}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"vue","class":"code-block code-block--with-filename"},"children":[{"type":"element","tag":"span","props":{"class":"code-block__filename"},"children":[{"type":"text","value":"FThreadFormReply.vue"}]},{"type":"element","tag":"code","props":{"code":"<template>\n  <f-form @submit=\"submitComment\">\n    <f-field-comment\n      label=\"Write a reply\"\n    />\n    <div class=\"flex\">\n      <p>Please make sure you've read our Forum Rules before replying.</p>\n      <f-button type=\"submit\">\n        Reply\n      </f-button>\n    </div>\n  </f-form>\n</template>\n","filename":"FThreadFormReply.vue","language":"vue"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"f-form"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"@"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"submit"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"submitComment"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"f-field-comment"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"label"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"Write a reply"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"flex"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"p"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"Please"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"make"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"sure"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"you"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"ve read our Forum Rules before replying.</p>"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"      <f-button type=\"submit\">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"        Reply"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"      </f-button>"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"    </div>"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"  </f-form>"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"</template>"}]}]}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"extra-and-optional-rules"},"children":[{"type":"text","value":"Extra and optional rules"}]},{"type":"element","tag":"h3","props":{"id":"use-an-automatic-component-importer"},"children":[{"type":"text","value":"Use An Automatic Component Importer"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Being tied to import paths once you have a few hundred components is going to slow you down."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Using an  "},{"type":"element","tag":"a","props":{"href":"/blog/vue-automatic-component-imports"},"children":[{"type":"text","value":"automatic component imports"}]},{"type":"text","value":" will clean up your code. You'll be free to tinker with the directory structure of your components in any way you want."}]},{"type":"element","tag":"h3","props":{"id":"typescript-components"},"children":[{"type":"text","value":"Typescript Components"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The value of types, when you're working with objects is too good to pass up. Will save you hours down the line in developer experience. As a starting point, I'd try and get your shared components using Typescript."}]},{"type":"element","tag":"CodeBlock","props":{"data-language":"vue","class":"code-block "},"children":[{"type":"element","tag":"code","props":{"code":"<script lang=\"ts\">\nimport type { PropType } from 'vue'\nimport { defineComponent } from 'vue'\nimport type { Post } from './types'\n\nexport default defineComponent({\n  props: {\n    post: {\n      type: Object as PropType<Post>,\n      required: true\n    }\n  },\n})\n</script>\n","language":"vue"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"script"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"lang"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"ts"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"type"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" { PropType } "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"vue"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" { defineComponent } "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"vue"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"type"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" { Post } "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F1FA8C"}},"children":[{"type":"text","value":"./types"}]},{"type":"element","tag":"span","props":{"style":{"color":"#E9F284"}},"children":[{"type":"text","value":"'"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"default"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#50FA7B"}},"children":[{"type":"text","value":"defineComponent"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"({"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  props"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    post"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      type"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"Object"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8BE9FD"}},"children":[{"type":"text","value":"PropType"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FFB86C"}},"children":[{"type":"text","value":"Post"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">,"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"      required"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#BD93F9"}},"children":[{"type":"text","value":"true"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"    }"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"  },"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"})"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#FF79C6"}},"children":[{"type":"text","value":"script"}]},{"type":"element","tag":"span","props":{"style":{"color":"#F8F8F2"}},"children":[{"type":"text","value":">"}]}]}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"components-have-one-job"},"children":[{"type":"text","value":"Components have \"one job\""}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Every component should have one job, any code in the component that isn't achieving that job shouldn't be there."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You should be thinking when you create a component what it's one core function is."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You can limit yourself with this mindset, but it's worth keeping in mind as you go."}]},{"type":"element","tag":"h3","props":{"id":"create-component-demo-pages"},"children":[{"type":"text","value":"Create component demo pages"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Using a package like "},{"type":"element","tag":"a","props":{"href":"https://storybook.js.org/","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Storybook"}]},{"type":"text","value":" is a great idea, but it comes with overhead and when you're starting out it can be a bit overkill."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a starting point, you can create pages under a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"/demo"}]},{"type":"text","value":" prefix and throw your components on it.\nYou want an easy way to find components and classes that are available."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Here is a rough demo page as an example: "},{"type":"element","tag":"a","props":{"href":"https://massivemonster.co/demo","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Massive Monster UI Demo"}]},{"type":"text","value":". Keep it as basic as you want."}]},{"type":"element","tag":"Image","props":{"alt":"Massive Monster Demo Page","height":445,"src":"/blog/brand-demo.png","width":900,"sizes":"md:900px sm:95vw xs:95vw"},"children":[]},{"type":"element","tag":"h3","props":{"id":"mixins-and-composables"},"children":[{"type":"text","value":"Mixins and composables"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This one should be pretty obvious and there are enough articles elsewhere on using these."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You want to pull out common logic from components and put them in either mixins or composables."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Check out "},{"type":"element","tag":"a","props":{"href":"https://github.com/antfu/vueuse","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"VueUse"}]},{"type":"text","value":" for some ideas on what that could look like."}]},{"type":"element","tag":"h2","props":{"id":"thanks-for-reading"},"children":[{"type":"text","value":"Thanks for reading"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you like the technical side of Vue and Laravel, I'll be posting regular articles on this site. The best\nway to keep up to date is by following me "},{"type":"element","tag":"a","props":{"href":"https://twitter.com/harlan_zw","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"@harlan_zw"}]},{"type":"text","value":" or signing up for the newsletter below."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"100-component-club","depth":2,"text":"100+ component club","children":[{"id":"problems-you-may-have","depth":3,"text":"Problems you may have"}]},{"id":"solving-component-scaling-with-rules","depth":2,"text":"Solving component scaling with rules","children":[{"id":"rule-0-have-good-dev-processes","depth":3,"text":"Rule 0. Have good dev processes"},{"id":"rule-1-know-the-style-guide","depth":3,"text":"Rule 1. Know the style guide"},{"id":"rule-2-use-a-component-naming-convention","depth":3,"text":"Rule 2. Use a component naming convention"},{"id":"rule-3-separate-component-scopes","depth":3,"text":"Rule 3. Separate component scopes"}]},{"id":"example-newsletter-sign-up","depth":2,"text":"Example: Newsletter Sign Up"},{"id":"example-forum-thread","depth":2,"text":"Example: Forum Thread"},{"id":"extra-and-optional-rules","depth":2,"text":"Extra and optional rules","children":[{"id":"use-an-automatic-component-importer","depth":3,"text":"Use An Automatic Component Importer"},{"id":"typescript-components","depth":3,"text":"Typescript Components"},{"id":"components-have-one-job","depth":3,"text":"Components have \"one job\""},{"id":"create-component-demo-pages","depth":3,"text":"Create component demo pages"},{"id":"mixins-and-composables","depth":3,"text":"Mixins and composables"}]},{"id":"thanks-for-reading","depth":2,"text":"Thanks for reading"}]}},"_type":"markdown","_id":"content:posts:scale-your-vue-components.md","_source":"content","_file":"posts/scale-your-vue-components.md","_extension":"md","storageMeta":{"atime":"2022-10-06T07:50:32.383Z","mtime":"2022-10-06T07:50:08.483Z","size":13640},"readingMins":6,"path":"/blog/scale-your-vue-components","renderer":"post","schemaOrg":{"modifiedAt":"2022-10-06T07:50:08.483Z"},"modifiedAt":"2022-10-06T07:50:08.483Z"}