Easy Tutorial
❮ Vue3 V If Vue3 Watch ❯

Vue3 Components

Components are one of the most powerful features of Vue.js.

Components can extend HTML elements and encapsulate reusable code.

The component system allows us to build large-scale applications using small, independently reusable components. Almost any type of application interface can be abstracted into a tree of components:

Each Vue application is created using the createApp function, with options passed to createApp to configure the root component. When we mount the application, this component is used as the starting point for rendering.

An application needs to be mounted to a DOM element.

In the following example, we mount the Vue application to <div id="app"></div>, and we should pass #app:

const RootComponent = { /* options */ }
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')

The syntax for registering a global component is as follows:

const app = Vue.createApp({...})

app.component('my-component-name', {
  /* ... */
})

my-component-name is the component name, and /* ... */ is the configuration options. After registration, we can call the component using:

<my-component-name></my-component-name>

A simple example of a Vue component:

Global Component Example

Register a simple global component tutorialpro and use it:

<div id="app">
    <tutorialpro></tutorialpro>
</div>

<script>
// Create a Vue application
const app = Vue.createApp({})

// Define a new global component named tutorialpro
app.component('tutorialpro', {
    template: '<h1>Custom Component!</h1>'
})

app.mount('#app')
</script>

Next, we register a button-counter component that increments the counter by 1 with each click:

Example

// Create a Vue application
const app = Vue.createApp({})

// Define a new global component named button-counter
app.component('button-counter', {
  data() {
    return {
      count: 0
    }
  },
  template: `
    &lt;button @click="count++">
      Clicked {{ count }} times!
    </button>`
})
app.mount('#app')
</script>

Note: The backticks in template are not single quotes '.

Component Reusability

You can reuse components as many times as needed:

Example

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

Global Components

In the above examples, our components were globally registered using component.

Globally registered components can be used in the template of any root component created afterwards, including all sub-components in the root component's tree.

Global Component Example

Register a simple global component tutorialpro and use it:

<div id="app">
    <tutorialpro></tutorialpro>
</div>

<script>
// Create a Vue application
const app = Vue.createApp({})

// Define a new global component named tutorialpro
app.component('tutorialpro', {
    template: '<h1>Custom Component!</h1>'
})

app.mount('#app')
</script>

Local Components

Global registration is often not ideal. For example, if you use a build system like webpack, global registration of all components means that even if you no longer use a component, it will still be included in your final build. This results in unnecessary JavaScript being downloaded by the user.

In such cases, you can define components as plain JavaScript objects:

const ComponentA = {
  /* ... */
}
const ComponentB = {
  /* ... */
}
const ComponentC = {
  /* ... */
}

Then define the components you want to use in the components option:

const app = Vue.createApp({
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

For each property in the components object, the property name is the custom element's name (component-a, component-b), and the property value is the component's option object (ComponentA, ComponentB).

We can also register local components in the instance options, making the component usable only within that instance:

Local Component Example

Register a simple local component tutorialproA and use it:

<div id="app">
    <tutorialpro-a></tutorialpro-a>
</div>
<script>
var tutorialproA = {
  template: '<h1>Custom Component!</h1>'
}

const app = Vue.createApp({
  components: {
    'tutorialpro-a': tutorialproA
  }
})

app.mount('#app')
</script>

Prop

A prop is a custom attribute for passing data from the parent component to the child component.

The parent component's data needs to be passed to the child component via props, and the child component needs to explicitly declare the prop using the props option:

Prop Example

<div id="app">
  <site-name title="Google"></site-name>
  <site-name title="tutorialpro"></site-name>
  <site-name title="Taobao"></site-name>
</div>

<script>
const app = Vue.createApp({})

app.component('site-name', {
  props: ['title'],
  template: `<h4>{{ title }}</h4>`
})

app.mount('#app')
</script>

A component can have any number of props, and any value can be passed to any prop.

Dynamic Prop

Similar to binding HTML attributes to an expression using v-bind, you can also use v-bind to dynamically bind props to data from the parent component. Whenever the parent component's data changes, the change is also propagated to the child component:

Prop Example

<div id="app">
  <site-info
    v-for="site in sites"
    :id="site.id"
    :title="site.title"
  ></site-info>
</div>

<script>
const Site = {
  data() {
    return {
      sites: [
        { id: 1, title: 'Google' },
        { id: 2, title: 'tutorialpro' },
        { id: 3, title: 'Taobao' }
      ]
    }
  }
}

const app = Vue.createApp(Site)

app.component('site-info', {
  props: ['id','title'],
  template: `<h4>{{ id }} - {{ title }}</h4>`
})

app.mount('#app')
</script>

Prop Validation

Components can specify validation requirements for props.

To customize prop validation, you can provide an object with validation requirements instead of an array of strings. For example:

Vue.component('my-component', {
  props: {
    // Basic type check (`null` and `undefined` will pass any type validation)
    propA: Number,
    // Multiple possible types
    propB: [String, Number],
    // Required string
    propC: {
      type: String,
      required: true
    },
    // Number with a default value
    propD: {
      type: Number,
      default: 100
    },
    // Object with a default value
    propE: {
      type: Object,
      // Object or array defaults must be returned from a factory function
      default: function () {
        return { message: 'hello' }
      }
    },
    // Custom validator function
    propF: {
      validator: function (value) {
        // The value must match one of these strings
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

When prop validation fails, Vue will produce a console warning (in development builds).

The type can be one of the following native constructors:

type can also be a custom constructor function, checked via instanceof.

❮ Vue3 V If Vue3 Watch ❯