Skip to content

Dumb Component Demo

Micah Godbolt edited this page Oct 16, 2018 · 3 revisions

Often called pure, or stateless components, a dumb component is one that you will render to the page and never think about again.

Creating our first component

We will be using Yeoman to scaffold out our new components.

npm run scaffold Link 

This will create a Link.vue, and Link.stories.js file in a Link folder in our components folder. Straight away you'll see that Storybook is able to render the new component file.

Looking over Link.vue

A Vue file is unique in that it contains everything your component needs to exist: Markup, JavaScript and Styles.

Template Tag

Inside of the template tags we'll add the following Vue flavored template.

<a class="Link" :href="href"> <slot/> </a>

The convention we're using is to capitalize the component name anywhere that it is used (Folder, File, Class etc). Think of the components name as a proper noun. This is only a convention we're using here (one of our road runner rules). Feel free to use whatever convention works best for you in your project.

The next thing to note is the : before the href. This is the shorthand notation for v-bind. This symbol signifies that the following attribute will be getting its value from a computed value, in this case the variable href.

Lastly the <slot/> element denotes the placeholder of where the child content of our Link component will be rendered. Therefore <Link>Hello</Link> will yield <a class="Link">Hello</a>.

You could also pass the Link text through as a property, like below.

<template>
  <a class="Link" :href="href"> {{text}} </a>
<template />
<Link text="Hello" href="#"/>

Script Tag

Jump down to the script tag and we can tell this component what type of data to expect.

export default {
  props: ["href"]
};

Export default means that this component is the default code exported from this file. You can provide a fixed name value here as well, but we're going to leave it out to keep things flexible.

The only thing we're going to be messing with in scripts is templates and props. Our link doesn't use any external templates so we only need to add our prop/s array. If you decided that the content of the tag should be a prop as well, you'd write props: ["href", "text"].

Styles Tag

Lastly, you'll see that we're given a blank style tag with lang=scss and the scoped keyword. This does 2 wonderful things.

Preprocessor Support

First off, without a single bit of work, you can now write Sass inside of this style tag. If you were to install a Less loader, you could write some components in Sass and others in Less, and the application wouldn't care.

Component Scoped Styles

The scoped keyword is even more magical. When this scoped mode is active, Vue creates a hash for each style, and applies that hash to the tag with the matching class name.

Now instead of just .Link as the selector, Vue uses .Link[data-v-1baa349f]. At the same time Vue adds this data attribute to the markup as well <a class="Link" data-v-1baa349f="">. This greatly reduces the change of one component's styles affecting another. We no longer need to use classes like .Link-icon because .icon in the Link won't have any effect on the .icon in the Button.

.Link {
  color: get-color(secondary);
}

We'll keep things simple and add just a single color style to this link. We're using a function coming from our utilities file that will return the secondary color from our color palette.

Adding Link to our application

Now that we have a component, lets add it to our application.

Back in App.vue we first need to import our new component:

import Link from "design-system/src/components/Link/Link.vue";

You'll notice I'm importing the link as Link. This name-spacing is done to make sure that none of our components conflict with default HTML elements. You can include this name-spacing into your folder and filenames as well if you prefer, but I prefer to let our Link simply be called Link.

Next we need to update the component object in our App.vue (it's just one big Vue Single File Component after all).

components: {
  Link
}

Lastly we can add our component into the template footer tag!

<p>Frontend Masters</p>
<p>Design System Workshop</p>
<p>With Micah Godbolt</p>
<p><Link href="https://twitter.com/micahgodbolt"> @micahgodbolt </Link></p>
<p><Link href="https://github.com/micahgodbolt/design-system-workshop-2.0"> Github </Link></p>

We'll eventually turn this into a component, but for now this demonstrates the full process of creating a component and seeing it rendered in our app.

That's it!

We covered a ton of important topics:

  • Yeoman Scaffolding
  • Single File Vue Components
  • Template tags with v-bind shorthand, slot and text interpolation
  • Script tags with components and props
  • Style tags with preprocessor support and scoped styles
  • Importing components into other files
  • Name spacing components to prevent conflicts with HTML elements
  • Using components in our App template

Exercise