components
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseComponents
组件
Table of Contents
目录
Vue components are the building blocks of Vue apps by allowing us to couple markup (HTML), logic (JS), and styles (CSS) within them.
When working within a Vue application, it's important to understand that almost every element displayed in the UI is oftentimes part of a Vue component. This is because a Vue application is often composed of components nested within components, forming a hierarchical structure.
When to Use
适用场景
- Use this as foundational knowledge for building any Vue application
- This is helpful for understanding how to structure, compose, and reuse UI elements in Vue
- 将此作为构建任何Vue应用的基础知识
- 这有助于理解如何在Vue中构建、组合和复用UI元素
Instructions
操作指南
- Use single-file components (files) with
.vue,<template>, and<script setup>sections<style> - Extract reusable parts of large components into smaller child components
- Use for reactive primitive values and
ref()for reactive objectsreactive() - Pass data from parent to child using props; emit events from child to parent
- 使用包含、
<template>和<script setup>部分的单文件组件(<style>文件).vue - 将大型组件中可复用的部分提取为更小的子组件
- 使用处理响应式原始值,使用
ref()处理响应式对象reactive() - 通过props将数据从父组件传递到子组件;子组件通过触发事件向父组件传递信息
Details
详细说明
Reusability and maintainability are some of the main reasons why building an application with well-structured components are especially important.
To get a better understanding of components, we'll go ahead and create one. The simplest way to create a Vue component in an application that doesn't contain a build process (e.g. Webpack) is to create a plain JavaScript object that contains Vue specific options.
js
export default {
props: ["name"],
template: `<h1>Hello, my name is {{ name }}</h1>`,
};The component has a property defined, which accepts a single prop named . Props are a way to pass data into a component from its parent component.
propsnameThe property defines the HTML template for the component. In this case, it contains an heading tag that displays the text followed by the value of the prop, which is rendered using Vue's double curly braces syntax .
template<h1>"Hello, my name is"name{{ }}Aside from defining components as plain JavaScript objects, the most common way of creating components in Vue are with single-file components (SFCs). Single-file components are components that allow us to define the HTML, CSS, and JS of a component all within a special file, as shown below:
.vuehtml
<template>
<h1>Hello, my name is {{ name }}</h1>
</template>
<script setup>
const { name } = defineProps(["name"]);
</script>Note: Single-file components in Vue are made possible due to build tools like Vite. These tools help compilecomponents to plain JavaScript modules that can be understood in browsers..vue
可复用性和可维护性是使用结构良好的组件构建应用的主要原因之一。
为了更好地理解组件,我们来创建一个组件。在没有构建流程(如Webpack)的应用中,创建Vue组件最简单的方式是创建一个包含Vue特定选项的普通JavaScript对象。
js
export default {
props: ["name"],
template: `<h1>Hello, my name is {{ name }}</h1>`,
};该组件定义了属性,它接受一个名为的prop。Props是从父组件向子组件传递数据的方式。
propsnametemplate<h1>"Hello, my name is"{{ }}name除了将组件定义为普通JavaScript对象外,Vue中最常见的创建组件的方式是使用单文件组件(SFC)。单文件组件允许我们在一个特殊的文件中定义组件的HTML、CSS和JS,如下所示:
.vuehtml
<template>
<h1>Hello, my name is {{ name }}</h1>
</template>
<script setup>
const { name } = defineProps(["name"]);
</script>注意:Vue中的单文件组件是通过Vite等构建工具实现的。这些工具会将组件编译为浏览器可以理解的普通JavaScript模块。.vue
Components = building blocks
组件=构建块
We'll go through a simple exercise to illustrate how components can be split into smaller components. Consider a fictional component.
TweetThe component can be implemented with something as follows:
html
<template>
<div class="Tweet">
<image class="Tweet-image" :src="image.imageUrl" :alt="image.description" />
<div class="User">
<image class="Avatar" :src="author.avatarUrl" :alt="author.name" />
<div class="User-name">{{ author.name }}</div>
</div>
<div class="Details">
<div class="Tweet-text">{{ text }}</div>
<div class="Tweet-date">{{ formatDate(date) }}</div>
<!-- ... -->
</div>
</div>
</template>
<script setup>
// ...
</script>One can look at the above component and consider it difficult to manipulate because of how clustered it is, and reusing individual parts of it may also prove difficult. To make things more composable, we can extract a few components from this one component.
We can have the main component be the parent to the and components. will display the user's information and be a parent to a component that displays the user's avatar. will simply display additional information in the tweet such as the tweet text and the date of submission.
TweetTweetUserTweetDetailsTweetUserTweetAvatarTweetDetailsWe can first create the child component to contain the avatar image element.
TweetAvatarhtml
<template>
<image class="Avatar" :src="author.avatarUrl" :alt="author.name" />
</template>
<script setup>
// ...
</script>We can then create the component that renders the component and relevant user information.
TweetUserTweetAvatarhtml
<template>
<div class="User">
<TweetAvatar />
<div class="User-name">{{ author.name }}</div>
</div>
</template>
<script setup>
import { TweetAvatar } from "./TweetAvatar.vue";
</script>We can create the component to render the remaining information in the tweet.
TweetDetailshtml
<template>
<div class="Details">
<div class="Tweet-text">{{ text }}</div>
<div class="Tweet-date">{{ formatDate(date) }}</div>
<!-- ... -->
</div>
</template>
<script setup>
// ...
</script>Finally, we can use these newly created child components to simplify the template of the parent component.
Tweethtml
<template>
<div class="Tweet">
<image class="Tweet-image" :src="image.imageUrl" :alt="image.description" />
<TweetUser :author="author" />
<TweetDetails :text="text" :date="date" />
</div>
</template>
<script setup>
// ...
</script>Extracting components seems like a tedious job, but having reusable components makes things easier when coding for larger apps. A good criterion to consider when simplifying components is this — if a part of your UI is used several times (, , ), or is complex enough on its own (, , ), it is a good candidate to be extracted into a separate component.
ButtonPanelAvatarAppFeedStoryComment我们通过一个简单的练习来说明如何将组件拆分为更小的组件。考虑一个虚构的组件。
Tweet该组件可以按如下方式实现:
html
<template>
<div class="Tweet">
<image class="Tweet-image" :src="image.imageUrl" :alt="image.description" />
<div class="User">
<image class="Avatar" :src="author.avatarUrl" :alt="author.name" />
<div class="User-name">{{ author.name }}</div>
</div>
<div class="Details">
<div class="Tweet-text">{{ text }}</div>
<div class="Tweet-date">{{ formatDate(date) }}</div>
<!-- ... -->
</div>
</div>
</template>
<script setup>
// ...
</script>有人可能会觉得上述组件结构过于繁杂,难以操作,而且复用其中的单个部分也很困难。为了提高可组合性,我们可以从这个组件中提取几个子组件。
我们可以让主组件作为和组件的父组件。将显示用户信息,并且是显示用户头像的组件的父组件。将显示推文的附加信息,如推文文本和发布日期。
TweetTweetUserTweetDetailsTweetUserTweetAvatarTweetDetails首先,我们创建子组件,包含头像图片元素。
TweetAvatarhtml
<template>
<image class="Avatar" :src="author.avatarUrl" :alt="author.name" />
</template>
<script setup>
// ...
</script>然后,我们创建组件,它会渲染组件和相关用户信息。
TweetUserTweetAvatarhtml
<template>
<div class="User">
<TweetAvatar />
<div class="User-name">{{ author.name }}</div>
</div>
</template>
<script setup>
import { TweetAvatar } from "./TweetAvatar.vue";
</script>我们创建组件来渲染推文中的剩余信息。
TweetDetailshtml
<template>
<div class="Details">
<div class="Tweet-text">{{ text }}</div>
<div class="Tweet-date">{{ formatDate(date) }}</div>
<!-- ... -->
</div>
</template>
<script setup>
// ...
</script>最后,我们可以使用这些新创建的子组件来简化父组件的模板。
Tweethtml
<template>
<div class="Tweet">
<image class="Tweet-image" :src="image.imageUrl" :alt="image.description" />
<TweetUser :author="author" />
<TweetDetails :text="text" :date="date" />
</div>
</template>
<script setup>
// ...
</script>提取组件看似繁琐,但拥有可复用的组件会让大型应用的开发变得更轻松。判断是否需要简化组件的一个标准是——如果UI的某一部分被多次使用(如、、),或者本身足够复杂(如、、),那么它就适合被提取为独立组件。
ButtonPanelAvatarAppFeedStoryCommentReactive state
响应式状态
Reactive state is a fundamental concept in Vue components that enables dynamic and responsive user interfaces. It allows components to update and reflect changes in their data automatically.
In Vue, we can define reactive data properties with the function (for standalone primitive values) and the function (for objects). Let's consider a simple example of a counter component:
ref()reactive()html
<template>
<div>
<h2>Counter: {{ count }}</h2>
<button @click="increment">Increment</button>
<button @click="decrement">Decrement</button>
</div>
</template>
<script setup>
import { ref } from "vue";
const count = ref(0);
const increment = () => {
count.value++;
};
const decrement = () => {
count.value--;
};
</script>In the above example, we define a reactive property and initialize it with a value of 0. The template then uses double curly braces to display the current value of .
count{{ }}countThe template also includes two buttons: and , which are bound to the corresponding and methods using the directive. Inside these methods, we access and modify the value of the reactive property. Vue detects the changes and automatically updates the component's rendering to reflect the new value.
"Increment""Decrement"increment()decrement()@clickcountReactive state in Vue components provides a seamless way to manage and track data changes, making it easier to build interactive and dynamic user interfaces.
响应式状态是Vue组件中的核心概念,它支持创建动态且响应式的用户界面。它允许组件自动更新并反映数据的变化。
在Vue中,我们可以使用函数(用于独立的原始值)和函数(用于对象)来定义响应式数据属性。我们来看一个简单的计数器组件示例:
ref()reactive()html
<template>
<div>
<h2>Counter: {{ count }}</h2>
<button @click="increment">Increment</button>
<button @click="decrement">Decrement</button>
</div>
</template>
<script setup>
import { ref } from "vue";
const count = ref(0);
const increment = () => {
count.value++;
};
const decrement = () => {
count.value--;
};
</script>在上述示例中,我们定义了一个响应式属性,并将其初始值设为0。模板通过双大括号显示的当前值。
count{{ }}count模板还包含两个按钮:和,它们通过指令绑定到对应的和方法。在这些方法中,我们访问并修改响应式属性的值。Vue会检测到这些变化,并自动更新组件的渲染以反映新值。
"Increment""Decrement"@clickincrement()decrement()countVue组件中的响应式状态提供了一种无缝的方式来管理和跟踪数据变化,使构建交互式和动态的用户界面变得更加容易。
Conclusion
总结
This article aims to be a simple introduction to the concept of components. In the other articles and guides, we'll be taking a deeper dive into understanding common and important patterns when working with Vue and Vue components. This includes but is not limited to:
- Using the syntax
<script setup> - Creating composables to reuse stateful logic
- Passing data down multiple components with provide/inject
- Understanding application-wide state management
- Using dynamic components to dynamically switch between components
- Rendering component templates with JSX
- and a lot more.
本文旨在简单介绍组件的概念。在其他文章和指南中,我们将更深入地探讨使用Vue和Vue组件时常见且重要的模式,包括但不限于: