Build Vue Components | Tutorial for Beginners

Vue is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects. On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.

Unlike Angular, which is based on the good old Model-View-Controller architecture, Vue follows a Model-View-View-Model system.

Another great thing about Vue is that it has single file components. This means that you can write the template, the script, and the style in a single .vue file.

<template>
  <p>({greeting })</p>
</template>
<script>
  module.exports = {
   data: function () {
      return {
        greeting: 'Hello'
      }
    }
  }
</script>
<style scoped>
  p {
    font-size: 2em;
    text-align: center;
  }
</style>

In this post, I will portray some of the best practices that you may want to keep in mind when building an advanced Vue App.

App Setup

There are many different ways that you can choose from for creating a Vue App.
In this post I am going to use the Vue CLI to create a Vue Project. First, open a command terminal in your system and write the following command to install the Vue CLI:

$ npm install --global @vue/cli


You can now create a Vue project! So lets go ahead and do that:

$ vue create vue-app
$ cd vue-app

This will create a new Vue project called vue-app. You can name it something else if you want.

Build Vue Components with vue-class-component

Take a look at the code snippet at the top of and you will see that you have a data function that returns an object. If you want to pass any handlers, you would have to write a method object.

vue-class-component reduces the component development process by allowing developers to add data properties and handlers directly as properties to the class.

Open your project directory in a code editor ( VS Code). In your src folder, you will notice two files: App.vue and main.js.

Developers with prior experience in libraries like React can say that the main.js file is equivalent to React’s index.js. Meaning this the actual file that gets launched when you run commands like yarn serve or yarn build.

Re-write the main.js file with the following code:


import 'tailwindcss/dist/tailwind.css';
import Vue from 'vue';
import App from './App';

new Vue ({
  el: '#app',
  render: h => <App />,
});

Basically, we are first grabbing a div element that has “app” as the id from the public/index.html file and then we are rendering the App component inside it.
You now need to create this App component inside the App.vue file. Open the App.vue file and replace the default code with this:


<template>
  <h1 @click="onClick">
    {{message}}
  </h1>
</template>

<script>
import Vue from 'vue';
import Component from 'vue-class-component';

export default Component({})(
  class App extends Vue {
    message = 'Batman';

    onClick() {
      this.message = 'Bruce Wayne';
    }
  }
);
</script>

Here, I first have created a simple template that has a div with a message inside it. The script imports the Vue package and the Component function from vue-class-component. You also need to install this package in your project.

$ yarn add vue-class-component

Next, I am decorating the App class with the Component function. This function has an object that you can pass in options.
If you are using VS Code, you will see that you are now getting an error on App. This is because VS Code by default does not accept experimental decorator. To solve this issue, create a new file called jsconfig.json in the project’s root directory. Here, you are telling the Vue Compiler to allow experimental decorators in your code:

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

Reload the editor and you will see the error disappear!

Now we answer the question, Why should I use vue-class-component instead of Vue’s traditional components?
In a traditional component, you are required to write a data function that returns an object. To change anything in your component, you will then write methods such an ``onClick```

const TraditionalComp = {
  data() {
    return {message: "Batman"}
  },
  methods:{
    onClick() {
      this.message = "Bruce Wayne"
    }
  }
}

But in vue-class-component, you directly write the onClick method. All that’s left to do is link it to the template. You can do this by writing @click="onClick" inside the template’s h1 tag.
Run the Vue app using the yarn serve command, and you will see it work like this:

This is image title

Define your Props with vue-property-decorator

You can also use vue-property-decorator to define the properties directly on the class. And that too is done with a simple @Prop() decorator. This method of prop declaration lets us keep our classes simple.

First, install the vue-property-decorator package in your project:

$ yarn add vue-property-decorator


Another great thing about this package is that it also includes the vue-class-component inside it. So you can instead import the Component from the vue-property-decorator package.

Inside the App.vue file, re-write the code as shown below:


<template>
  <h1 @click="onClick">
    {{message}}
  </h1>
</template>

<script>
import Vue from 'vue';
import {Component, Prop} from 'vue-property-decorator';

export default Component({})(
  class App extends Vue {
    @Prop({default: 'Batman'})
    message;

    onClick() {
      this.message = 'Bruce Wayne';
    }
  }
);
</script>

Here, I am first importing the Component and Prop from the vue-property-decorator package. Then inside the App class, I am using the @Prop decorator to set the default value of the message.

And that’s it! You are now passing the message as prop to our code, and it also has a default value.

Define the Content’s Place in Components with Vue Slots

Vue’s slots lets you tell your code where you want your content to be in the component. This may sound confusing now, so let’s see what slots actually do for us with some coding.

Back in the main.js file, re-write the code inside render like this:

render: h => (
  <App>
    <h1>Superman</h1>
  </App>
)

If you take a look at the app in your browser, you will see that nothing has changed. This is because you have not specified any place for the new text inside the template in App.vue file. This is where slots come into play.
Inside App.vue‘s template, write two new slots that wrap the original h1 tag.

<template>
  <div>
    <slot name="header"></slot>
    <h1 @click="onClick">
      {{message}}
    </h1>
    <slot name="footer"></slot>
  </div>
</template>

Your app still won’t render the new text. That’s because the compiler now doesn’t know which slot to put the new text in. I want the text to be in the bottom slot. I have given this slot a name of footer.

Go to main.js file, and add an attribute of slot="footer" to the new text. This will then render the new text.

But your render method is a bit unwieldy now. Let’s see how you can use slots to take care of that.

Use Slots to Create Layouts

You can also use slots to create custom layouts that can be used to specify where each piece of your app or component should be placed.
Create a new file called Layout.vue inside the src/components folder. Inside this file, write a template element as shown below:


<template>
  <div>
    <slot name="header"></slot>
    <slot name="body"></slot>
    <slot name="footer"></slot>
  </div>
</template>

Next, go into the App.vue file and delete everything inside the template tag. Then, inside the script tag, import the Layout.vue that you just created, like this:


import Layout from './components/Layout';


You also need to tell the Component decorator that you are using the Layout as a component.

export default Component({
  components: {Layout},
})

You can now use the Layout as a component inside the template tag. I am going to also add a few text tags.


<template>
  <Layout>
    <h1 slot="header">How To Build Vue Apps Like A Pro 😎</h1>
    <h2 slot="body"> by Rajat S</h2>
    <h3 slot="footer">Technical Content Writer</h3>
  </Layout>
</template>


Make sure that you have added a slot attribute with the appropriate name, else the text tags will not get rendered.

Passing Props using Vue Slot Scope

By combining your components with slots, you can pass the component’s data into slot using slot-scope. You can pass props down from Parent components to Child components without coupling them together.

Go to the App.vue file and inside the template tag, wrap the Layout inside a Settings tag.

<template>
  <Settings>
    <Layout slot-scope="{header}">
      <h1 slot="header">{{header}}</h1>
      <h2 slot="body"> by Rajat S</h2>
      <h3 slot="footer">Technical Content Writer</h3>
    </Layout>
  </Settings>
</template>

Import the Settings inside the script tag,

import Settings from './components/Settings.vue';

Tell the Component decorator that you are using Settings as a component.

export default Component({
  components: {Layout, Settings},
})

Now, you actually need to create the Settings component. So go to src/components and create a file named Settings.vue. Write this code inside it:


<template>
  <div>
    <slot :header="header"></slot>
  </div>
</template>
<script>
import Vue from 'vue';
import Component from 'vue-class-component';
export default Component({})(
  class Settings extends Vue {
    header = 'How To Build Vue Apps Like A Pro 😎';
  }
);
</script>

Inside the template tag, I have a root div that has slot inside it. Inside this slot, I’m binding :header to header.

Moving on to the script tag, I am first importing the Vue package and the Component decorator from vue-class-component package.

Then I create a Header class inside the Component decorator. This class contains the data that I want to pass on to the header prop.

Passing Props to Functional Templates

Functional templates allows you to create a component that only has a template tag and exposes the props into the template.
Inside the src/components folder, create a new file called Header.vue write this code inside it:

<template functional>
  <h1 slot="header">{{props.header}}</h1>
</template>

The term functional here is used to indicate that this file only has a simple template. Repeat this for Body.vue and Footer.vue files.
Return to the App.vue file and re-write the template like this:


<template>
  <Settings>
    <Layout slot-scope="{header, body, footer}">
      <Header slot="header" :header="header"></Header>
      <Body slot="body" :body="body"></Body>
      <Footer slot="footer" :footer="footer"></Footer>
    </Layout>
  </Settings>
</template>

You also need to write the import statements for the Header, Body, Footer inside the file’s script tag:

import {Header, Body, Footer} from './components';

And tell the Component decorator that you are using these as components.


export default Component({
  components: {
    Settings,
    Layout,
    Header,
    Body,
    Footer,
  },
})

But the code still won’t work. Because the import statement that you just wrote is not entirely correct. To solve this issue, create a new file called index.js inside src/components.

export {default as Header} from ‘./Header.vue’;
export {default as Body} from ‘./Body.vue’;
export {default as Footer} from ‘./Footer.vue’;

With this, you have created Functional Templates in Vue that allows us to pass our props from a Parent component to a Child component, without having to write much code.

The article comes here is the end With this, you have created Functional Templates in Vue that allows us to pass our props from a Parent component to a Child component, without having to write much code.

#vue #vuejs #javascript

Build Vue Components | Tutorial for Beginners
1 Likes5.65 GEEK