Introduction to 0,
Before we dive into components, let’s take a look at a simple example:
<! DOCTYPEhtml>
<html>
<head>
<title>Demo</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<button-counter></button-counter>
</div>
<script>
Vue.component('button-counter', {
data: function () {
return {
count: 0}},template: '<button v-on:click="count++">{{ count }} times</button>'
})
new Vue({
el: '#app'
})
</script>
</body>
</html>
Copy the code
Let’s take a closer look at the code above:
Vue.component('button-counter', {
data: function () {
return {
count: 0}},template: '<button v-on:click="count++">{{ count }} times</button>'
})
Copy the code
We first created a global component called button-Counter using the global method Vue.component()
The first argument to this method is the component name, and the second argument is the option object, which contains two properties, data and template
The data property is a function that returns an object to store dynamically changing data
It is defined as a function because a component can be used to create multiple instances, and if defined as an object, all instances will share the same data object
The template property is a template string that defines the HTML code for the component
Note that the component must be a single root element, meaning that the contents of the template must be wrapped in a parent element
<div id="app">
<button-counter></button-counter>
</div>
Copy the code
We can then use this component as a custom element in a root instance created with new Vue()
Ok, now that you have a basic understanding of the components, let’s go over them in detail
1. Component registration
Components are reusable Vue instances, and before using them, we need to register them so that Vue can recognize them
(1) Component registration has two parameters, namely component name and option object
- Component name
There are two ways to define component names: kebab-case (dash delimited name) and PascalCase (uppercase name)
Kebab-case: Kebab-case is used when referencing
PascalCase: Both nomenclature are available when used in templates; When used in the DOM, only kebab-case is valid
- The options object
This object receives options similar to those received by new Vue(), with the exception of options specific to root instances like EL
(2) There are two ways to register components, which are global registration and local registration
- Global registration
We can register globally using the global method Vue.component(), whose first argument is the component name and the second argument is the option object
Globally registered components can be used in any newly created root instance
Vue.component('component-a', { / *... * / })
Vue.component('component-b', { / *... * / })
new Vue({ el: '#app' })
Copy the code
- Local registration
We can locally register with option Components when we create the root instance, which is an object with the key being the component name and the value being the option object
A locally registered component cannot be used in its children, that is, the two components in the following example cannot call each other internally
var ComponentA = { / *... * / }
var ComponentB = { / *... * / }
new Vue({
el: '#app'.components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
Copy the code
To make ComponentA available for ComponentB, we need to write it differently:
var ComponentA = { / *... * / }
var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}
Copy the code
2. Pass data to child components — prop
A PROP is a set of custom features registered with a component, and when a value is passed to a PROP feature, it becomes a property of the component instance
(1) Pass static prop
In this example, we pass a static value to prop, Title Here
<! DOCTYPEhtml>
<html>
<head>
<title>Demo</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<title-item title="Title Here"></title-item>
</div>
<script>
Vue.component('title-item', {
props: ['title'].template: '<h3>{{ title }}</h3>'
})
new Vue({
el: '#app'
})
</script>
</body>
</html>
Copy the code
(2) Pass dynamic prop
In the following example, we bind prop to a dynamic object, Content, via V-bind
<! DOCTYPEhtml>
<html>
<head>
<title>Demo</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<title-item v-bind:title="content.title"></title-item>
</div>
<script>
Vue.component('title-item', {
props: ['title'].template: '<h3>{{ title }}</h3>'
})
new Vue({
el: '#app'.data: {
content: {
'title': 'Title Here'}}})</script>
</body>
</html>
Copy the code
(3) Prop type and PROP verification
In both of the examples above, props is an array of strings, where each prop is a string
But there are other types of prop
At this point we can list prop as an object, where the key of the object is the name of the prop and the value of the object is the type of the prop
Vue.component('my-component', {
props: {
propA: String.propB: Number.propC: Boolean.propD: Array.propE: Object.propF: Function
// ...
},
// ...
})
Copy the code
Now that a prop has a type, we need to determine whether the prop conforms to the type. We can customize the validation method of the prop (here is an example from the official documentation).
Vue.component('my-component', {
props: {
// Basic type checking (' null 'and' undefined 'will pass any type verification)
propA: Number.// Multiple possible types
propB: [String.Number].// A mandatory string
propC: {
type: String.required: true
},
// A number with default values
propD: {
type: Number.default: 100
},
// Objects with default values
propE: {
type: Object.// Object or array defaults must be obtained from a factory function
default: function () {
return { message: 'hello'}}},// Customize the validation function
propF: {
validator: function (value) {
This value must match one of the following strings
return ['success'.'warning'.'danger'].indexOf(value) ! = = -1}}}})Copy the code
Vue (development environment build) will generate a console warning when prop validation fails
3. Pass data to the parent — custom events
Prop is a one-way downlink binding, meaning that updates to the parent prop flow down to the child component, but not the other way around
If a child component wants to pass data to its parent, it needs to use a custom event
The parent component can listen for any event of the child component instance via V-ON, and the child component can fire events via $emit()
(1) Listen for sub-component events
<! DOCTYPEhtml>
<html>
<head>
<title>Demo</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
<script>
Vue.component('button-counter', {
template: '<button v-on:click="incrementHandler">{{ counter }}</button>'.data: function () {
return {
counter: 0}},methods: {
incrementHandler: function () {
this.counter += 1
this.$emit('increment')}}})new Vue({
el: '#app'.data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1}}})</script>
</body>
</html>
Copy the code
Let’s take a closer look at the above code:
Vue.component('button-counter', {
template: '<button v-on:click="incrementHandler">{{ counter }}</button>'.data: function () {
return {
counter: 0}},methods: {
incrementHandler: function () {
this.counter += 1
this.$emit('increment')}}})Copy the code
First, we define a component called button-Counter
The child component button-Counter uses V-on to listen for the native event Click, whose handler is incrementHandler()
IncrementHandler () increments counter (the data in the child component) by 1 and then raises the custom event increment
<div id="app">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
Copy the code
new Vue({
el: '#app'.data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1}}})Copy the code
Increment (incrementTotal()) ¶ Increment (incrementTotal()) ¶ increment (incrementTotal()) ¶
In incrementTotal(), increase the value of total (the data in the root component) by 1
(2) Throw a value through the event
We can throw a value in the second argument to the $emit() function
Vue.component('button-counter', {
template: '<button v-on:click="incrementHandler">{{ counter }}</button>'.data: function () {
return {
counter: 0}},methods: {
incrementHandler: function () {
this.counter += 1
this.$emit('increment'.2)}}})Copy the code
And receives the value in the first argument to the event handler
new Vue({
el: '#app'.data: {
total: 0
},
methods: {
incrementTotal: function (value) {
this.total += value
}
}
})
Copy the code