============各位看官,点波关注和赞吧===========
组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构:
这和我们嵌套 HTML 元素的方式类似,Vue 实现了自己的组件模型,使我们可以在每个组件内封装自定义内容与逻辑。Vue 同样也能很好地配合原生 Web Component(网络组件)。
🌲 定义一个组件
当使用构建步骤时,我们一般会将 Vue 组件定义在一个单独的 .vue 文件中,这被叫做单文件组件 (简称 SFC):
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">You clicked me {
{ count }} times.</button>
</template>
🌲 使用组件
要使用一个子组件,我们需要在父组件中导入它。假设我们把计数器组件放在了一个叫做 Counter.vue 的文件中,这个组件将会以默认导出的形式被暴露给外部。
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">You clicked me {
{ count }} times.</button>
</template>
在App.vue中可以这样引用
<script setup>
import ButtonCounter from './components/Counter.vue'
</script>
<template>
<h2> 下面是一个子组件</h2>
<ButtonCounter></ButtonCounter>
</template>
组件可以被重用任意多次:
<h1>这里是一个子组件!</h1>
<ButtonCounter />
<ButtonCounter />
<ButtonCounter />
你会注意到,每当点击这些按钮时,每一个组件都维护着自己的状态,是不同的 count。这是因为每当你使用一个组件,就创建了一个新的实例。
在单文件组件中,推荐为子组件使用 驼峰命名法的标签名,以此来和原生的 HTML 元素作区分。虽然原生 HTML 标签名是不区分大小写的,但 Vue 单文件组件是可以在编译中区分大小写的。我们也可以使用 /> 来关闭一个标签。
🌲 传递Props
🌾 Props初体验
如果我们正在构建一个博客,我们可能需要一个表示博客文章的组件。我们希望所有的博客文章分享相同的视觉布局,但有不同的内容。要实现这样的效果自然必须向组件中传递数据,例如每篇文章标题和内容,这就会使用到 props。
Props 是一种特别的 attributes,你可以在组件上声明注册。要传递给博客文章组件一个标题,我们必须在组件的 props 列表上声明它。这里要用到 defineProps 宏:
<!-- BlogPost.vue -->
<script setup>
const props = defineProps(['title'])
console.log(props.title)
</script>
<template>
<h4>{
{ title }}</h4>
</template>
defineProps 是一个仅 <script setup> 中可用的编译宏命令,并不需要显式地导入。声明的 props 会自动暴露给模板。defineProps 会返回一个对象,其中包含了可以传递给组件的所有 props.
一个组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值。
当一个 prop 被注册后,可以像这样以自定义 attribute 的形式传递数据给它:
<script setup>
import BlogPost from './components/BlogPost.vue'
</script>
<template>
<BlogPost title="山海经"></BlogPost>
</template>
在实际应用中,我们可能在父组件中会有如下的一个博客文章数组:
<script setup>
import {ref} from 'vue'
import BlogPost from './components/BlogPost.vue'
const posts = ref([
{id:1,title:"钢铁是怎样练成的"},
{id:2,title:"坏蛋是怎样练成的"},
{id:3,title:"秦始皇是怎样练成的"},
])
</script>
<temp