Vue.js' component architecture makes building a user interface efficient and convenient. It allows you to break down your application into smaller, reusable components and then build more complex structures with these components.
This guide will provide you with an advanced introduction to Vue components. We will explore how to create components, how to pass data between components (via props and event buses), and how to render additional content within components using Vue's <slot></slot>
element. Each example will come with a runnable CodePen demo.
Key Points
- Vue's componentized architecture helps break down the UI into reusable, easy-to-manage snippets, thereby enhancing the reusability and organization of the code.
- Components can be created globally using
Vue.component
or locally in single-file components. For complex projects, the latter is more suitable for use because of its encapsulation of templates, scripts, and styles. - The data can be passed to subcomponents using props, providing a clear and structured way to manage and pass data in the component tree.
- The event bus can be used to effectively manage communication from child components to parent components, allowing child components to send data back to the component hierarchy.
- Vue's
<slot></slot>
element helps nest content within the component, making it more flexible and able to receive content from the parent component, which can be overwritten with fallback content.
How to create components in Vue
Components are essentially reusable Vue instances with names. There are many ways to create components in a Vue application. For example, in small to medium-sized projects, you can register global components using the Vue.component
method as follows:
Vue.component('my-counter', { data() { return { count: 0 } }, template: `<div>{{ count }}</div>` }) new Vue({ el: '#app' })</pre> The name of thecomponent is
my-counter
. It can be used like this:<div> <my-counter></my-counter> </div></pre> When naming a component, you can choose to use kebab-case () or Pascal-case (
is a function that returns the object literal (rather than the object literal itself). The purpose of this is to let each instance of the component have its own data object without having to share a global instance with all other instances.my-custom-component
). When referencing components in templates, either variant can be used, but when referencing components directly in the DOM (as shown in the above example), only theMyCustomComponent
kebab-case tag name is valid. You may also notice that in the above example,or templates inside the DOM. You can read more about the different ways to define templates here.
data
There are several ways to define component templates. Above we used template literals, but we can also use markers withSingle file component
text/x-template
In more complex projects, global components can quickly become difficult to manage. In this case, it makes sense to design your application to use a single file component. As the name implies, these are single files with
.vue
extensions that contain<template>
,</pre>
And the MyCounter component may look like this:
Vue.component('my-counter', { data() { return { count: 0 } }, template: `<div>{{ count }}</div>` }) new Vue({ el: '#app' })</pre>As you can see, when using single file components, you can import and use them directly in the components that require them.
method to register the component to show all the examples.
Vue.component()
In this guide, I will use theUsing single-file components often involves building steps (for example, using Vue CLI). If you want to learn more, check out the "Vue CLI Getting Started Guide" in this Vue series.
Transfer data to components via Props
Props enables us to pass data from parent component to child component. This allows our components to be divided into smaller chunks to handle specific functions. For example, if we have a blog component, we might want to display information such as author details, post details (title, body, and image), and comments.
We can break these into child components so that each component processes specific data, making the component tree look like this:
<div> <my-counter></my-counter> </div></pre>If you still don't believe in the benefits of using components, take a moment to realize how useful this combination is. If you want to revisit this code in the future, you will immediately be clear on how the page is built and where you should look for which functionality (i.e. in which component). This declarative way of combining interfaces also makes it easier for those who are not familiar with the code base to get started quickly and improve efficiency.
Since all data will be passed from the parent component, it might look like this:
<template> <div>{{ count }}</div> </template> <??></pre>. Therefore, our HTML template will look like this:
author-detail
In the above example component, we define the author details and post information. Next, we have to create the child components. Let's name the child component<blogpost> <authordetails></authordetails> <postdetails></postdetails> <comments></comments> </blogpost></pre>, which we define in the parent component.
owner
We pass the author object to the child component as props namedowner
. There is a need to pay attention to the difference here. In a child component,author
is the props name that we receive data from the parent component. The data we want to receive is calledcomponent:
author-detail
To access this data, we need to declare props in thenew Vue({ el: '#app', data() { return { author: { name: 'John Doe', email: 'jdoe@example.com' } } } })</pre>We can also enable verification when passing props to ensure the correct data is passed. This is similar to PropTypes in React. To enable verification in the example above, change our component to look like this:
<div> <author-detail :owner="author"></author-detail> </div></pre>If we pass the wrong prop type, you will see an error in the console similar to what I've shown below:
Vue.component('author-detail', { template: ` <div> <h2>{{ owner.name }}</h2> <p>{{ owner.email }}</p> </div> `, props: ['owner'] })</pre>There is an official guide in the Vue documentation that you can use to understand prop verification.
Communication from child component to parent component via event bus
<script></code> 和 <code><style></code> 部分。</p> <p>對于上面的示例,App 組件可能如下所示:</p> <pre class="brush:php;toolbar:false"><code class="vue"><template> <div> <my-counter></my-counter> </div> </template> <script> import myCounter from './components/myCounter.vue' export default { name: 'app', components: { myCounter } } </script>Events are handled by creating wrapper methods that are triggered when the selected event occurs. To review, let's expand based on our initial counter example so that it increases every time the button is clicked.
Our components should look like this:
Vue.component('my-counter', { data() { return { count: 0 } }, template: `<div>{{ count }}</div>` }) new Vue({ el: '#app' })</pre>and our template:
<div> <my-counter></my-counter> </div></pre>This hope is simple enough. As you can see, we are connecting to the
onClick
event to trigger a customincrease
method every time the button is clicked. Theincrease
method then increments ourcount
data attributes. Now let's expand the example, move the counter button into a separate component and display the count in the parent component. We can do this using event bus.Event bus is very convenient when you want to communicate from child components to parent components. This is contrary to the default communication method, which is from the parent component to the child component. If your application isn't big enough to not need Vuex, you can use the event bus. (You can read more about it in the "Vuex Getting Started Guide" in this Vue series.)
So what we have to do is: the count will be declared in the parent component and passed down to the child component. Then in the child component, we want to increment the value of
count
and make sure that the value in the parent component is updated.App components will look like this:
<template> <div>{{ count }}</div> </template> <??></pre>Then in the child component, we want to receive the count through props and have a way to increment it. We do not want to display the value of
count
in the child component. We just want to increment from the child component and make it reflect in the parent component:<blogpost> <authordetails></authordetails> <postdetails></postdetails> <comments></comments> </blogpost></pre>Then our template will look like this:
new Vue({ el: '#app', data() { return { author: { name: 'John Doe', email: 'jdoe@example.com' } } } })</pre>If you try to increment the value like that, it won't work. In order for it to work, we have to issue an event from the child component, send a new value of
count
, and also listen for this event in the parent component.First, we create a new Vue instance and set it to
eventBus
:<div> <author-detail :owner="author"></author-detail> </div></pre>We can now use event bus in our components. The subcomponent will look like this:
Vue.component('author-detail', { template: ` <div> <h2>{{ owner.name }}</h2> <p>{{ owner.email }}</p> </div> `, props: ['owner'] })</pre>Events every time the
increment
method is called. We have to listen for the event in the main component and setcount
to the value we get from the emitted event:Vue.component('author-detail', { template: ` <div> <h2>{{ owner.name }}</h2> <p>{{ owner.email }}</p> </div> `, props: { owner: { type: Object, required: true } } })</pre>Note that we are using Vue's
created
lifecycle method to connect to the component before it is mounted and set up the event bus.If your application is not complex, using event bus is good, but remember that as your application grows, you may want to use Vuex instead.
Use contents in nested components of Slots
In the examples we have seen so far, the components are self-closing elements. However, in order to create components that can be grouped together in a useful way, we need to be able to nest them with each other like we would with HTML elements.
If you try to use a component with an end tag and put some content inside, you will see that Vue just swallowed it. Anything between the start and end tags of a component will be replaced by the rendering output of the component itself:
Vue.component('my-counter', { data() { return { count: 0 } }, template: `<div>{{ count }}</div>` }) new Vue({ el: '#app' })</pre>Luckily, Vue's slots make it possible to pass arbitrary values ??to the component. This can be anything from the parent component to the child component, from the DOM element to other data. Let's see how they work.
The script part of thecomponent will look like this:
<div> <my-counter></my-counter> </div></pre>Then the template will look like this:
<template> <div>{{ count }}</div> </template> <??></pre> The content in the
<list>
component will be rendered between the<slot>
element labels. We can also use fallback content in case the parent component does not inject anything.<blogpost> <authordetails></authordetails> <postdetails></postdetails> <comments></comments> </blogpost></pre>If there is no content from the parent component, the fallback content will be rendered.
Conclusion
This is a high-level introduction to using components in Vue. We looked at how to create components in Vue, how to communicate from parent to child components via props, and how to communicate from child to parent components over the event bus. We then end up by looking at slots, a convenient way to combine components in a useful way. I hope you find this tutorial useful.
(The FAQs part is omitted because it is too long and does not match the pseudo-original goal. Some of the FAQs content can be re-written as needed, but the original intention must be kept unchanged.)
The above is the detailed content of A Beginner's Guide to Working With Components in Vue. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics









The following points should be noted when processing dates and time in JavaScript: 1. There are many ways to create Date objects. It is recommended to use ISO format strings to ensure compatibility; 2. Get and set time information can be obtained and set methods, and note that the month starts from 0; 3. Manually formatting dates requires strings, and third-party libraries can also be used; 4. It is recommended to use libraries that support time zones, such as Luxon. Mastering these key points can effectively avoid common mistakes.

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

Event capture and bubble are two stages of event propagation in DOM. Capture is from the top layer to the target element, and bubble is from the target element to the top layer. 1. Event capture is implemented by setting the useCapture parameter of addEventListener to true; 2. Event bubble is the default behavior, useCapture is set to false or omitted; 3. Event propagation can be used to prevent event propagation; 4. Event bubbling supports event delegation to improve dynamic content processing efficiency; 5. Capture can be used to intercept events in advance, such as logging or error processing. Understanding these two phases helps to accurately control the timing and how JavaScript responds to user operations.

If JavaScript applications load slowly and have poor performance, the problem is that the payload is too large. Solutions include: 1. Use code splitting (CodeSplitting), split the large bundle into multiple small files through React.lazy() or build tools, and load it as needed to reduce the first download; 2. Remove unused code (TreeShaking), use the ES6 module mechanism to clear "dead code" to ensure that the introduced libraries support this feature; 3. Compress and merge resource files, enable Gzip/Brotli and Terser to compress JS, reasonably merge files and optimize static resources; 4. Replace heavy-duty dependencies and choose lightweight libraries such as day.js and fetch

The main difference between ES module and CommonJS is the loading method and usage scenario. 1.CommonJS is synchronously loaded, suitable for Node.js server-side environment; 2.ES module is asynchronously loaded, suitable for network environments such as browsers; 3. Syntax, ES module uses import/export and must be located in the top-level scope, while CommonJS uses require/module.exports, which can be called dynamically at runtime; 4.CommonJS is widely used in old versions of Node.js and libraries that rely on it such as Express, while ES modules are suitable for modern front-end frameworks and Node.jsv14; 5. Although it can be mixed, it can easily cause problems.

There are three common ways to initiate HTTP requests in Node.js: use built-in modules, axios, and node-fetch. 1. Use the built-in http/https module without dependencies, which is suitable for basic scenarios, but requires manual processing of data stitching and error monitoring, such as using https.get() to obtain data or send POST requests through .write(); 2.axios is a third-party library based on Promise. It has concise syntax and powerful functions, supports async/await, automatic JSON conversion, interceptor, etc. It is recommended to simplify asynchronous request operations; 3.node-fetch provides a style similar to browser fetch, based on Promise and simple syntax

JavaScript's garbage collection mechanism automatically manages memory through a tag-clearing algorithm to reduce the risk of memory leakage. The engine traverses and marks the active object from the root object, and unmarked is treated as garbage and cleared. For example, when the object is no longer referenced (such as setting the variable to null), it will be released in the next round of recycling. Common causes of memory leaks include: ① Uncleared timers or event listeners; ② References to external variables in closures; ③ Global variables continue to hold a large amount of data. The V8 engine optimizes recycling efficiency through strategies such as generational recycling, incremental marking, parallel/concurrent recycling, and reduces the main thread blocking time. During development, unnecessary global references should be avoided and object associations should be promptly decorated to improve performance and stability.

The difference between var, let and const is scope, promotion and repeated declarations. 1.var is the function scope, with variable promotion, allowing repeated declarations; 2.let is the block-level scope, with temporary dead zones, and repeated declarations are not allowed; 3.const is also the block-level scope, and must be assigned immediately, and cannot be reassigned, but the internal value of the reference type can be modified. Use const first, use let when changing variables, and avoid using var.
