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: `
<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:
String
Number
Boolean
Array
Object
Date
Function
Symbol
type
can also be a custom constructor function, checked via instanceof
.