Vue组件树:从设计到实现的全方位指南 🚀

Vue组件树:从设计到实现的全方位指南 🚀

组件化开发:Vue的核心思想

Vue 的核心思想之一就是组件化开发,而组件树(Component Tree)则是 Vue 应用的基础结构。组件化开发不仅能提高代码复用性,还能让项目结构更清晰,便于团队协作和维护。

页面组件化实战

组件化设计示例

如下图的页面,我们将页面组件化后得到右边的组件树:

结合上面的图,用组件化的思想设计出下面的页面结构:

一个实际的页面,将其组件化后得到了一棵包含多个组件的组件树。比如,一个常见的网页布局包含:

  • 顶部的导航栏
  • 侧边的侧边栏
  • 主体内容区域

我们可以把这些部分分别抽象成 AppHeader、AppAside、AppMain 组件,再加上 AppAside 的子组件 User,AppMain 的子组件 Item。整个页面则由 App 组件来统筹管理这些子组件的组合与交互。

组件树结构

抽象为组件树,即下面的模式:

markdown 复制代码
App
├── AppHeader
├── AppMain
│   ├── Item
│   └── Rate
└── AppAside
    └── User

在 Vue DevTools 中应该呈现出这样的组件树结构:

详细设计思路

设计流程

  1. 静态页面设计阶段:

    markdown 复制代码
    App
    ├── AppHeader
    ├── AppMain
    │   └── Item
    └── AppAside
        └── User
  2. 动态功能扩展阶段 :

    在 AppMain 中再设计 Rate 组件,采用父组件向子组件传递信息的方式:

    复制

    复制代码
    AppMain
    ├── Rate
    └── Item

代码实现详解

App

xml 复制代码
<script setup>
import AppAside from './components/AppAside.vue'
import AppHeader from './components/AppHeader.vue'
import AppMain from './components/AppMain.vue'

</script>

<template>
  <!-- LayOut -->
  <div class="contaner">
      <AppHeader/>
      <!--  布局 : 弹性 -->
      <div class="flx">
          <AppMain/>
          <AppAside/>
      </div>
  </div>
</template>

<style scoped>
.flx {
  display : flex;
}
</style>

导入相关组件

  • 在App.vue文件中,我们首先导入了AppAside、AppHeader和AppMain组件,以便在模板中使用它们。

模板布局


  • 模板中使用div元素进行布局,外层的div设置类为contaner,内部AppHeader独占一行,接着是一个类为flx的div,在这个弹性布局容器中,AppMain和AppAside并列排放,并且AppMain会占据剩余空间(通过flex: 1设置)。

AppHeader

xml 复制代码
<template>
     <Header>
        Header
    </Header>
</template>

<script setup>

</script>

<style  scoped>
header {
    height : 100px;
    background-color: #37372c;
}
</style>

模板内容

  • 模板非常简单,只有一个Header标签,用于显示页面头部的内容,比如网站的 logo、标题等。

样式设置

  • 样式中设置了背景颜色为#37372c,高度为 100px,给头部一个明确的视觉效果。

AppMain

在该组件里 , 父组件是 AppMain , 子组件是 Item

xml 复制代码
<template>
   <main>
    Main
    <Item/>
    <Item/>
   </main>
</template>

<script setup>
import Item from './Item.vue'
import {ref} from 'vue'

</script>

<style  scoped>
main {
   flex : 1;
   height: 500px;
   background-color: rgb(136, 111, 137);
}
</style>

Item

xml 复制代码
<template>
    <div>
        Item
    </div>
</template>

<script setup>

</script>

<style scoped>
div{
    height:100px;
    background-color: aquamarine;
    margin:10px;
}
</style>

模板展示

  • 模板中是一个简单的div标签,用于显示具体的项目内容,比如列表项、文章摘要等。

样式调整

  • 样式中设置div高度为 100px,背景颜色为aquamarine,外边距为 10px,使每个项目在页面上有一定的间隔和视觉区分。

AppAside

xml 复制代码
<template>
    <aside class = "flx">
        Aside
        <User/>
        <User/>
        <User/>
    </aside>
</template>

<script setup>
import User from './User.vue'
</script>

<style  scoped>
aside{
    width:200px;
    height:500px;
    background-color: rgb(109, 90, 54);
}
</style>

导入用户组件

  • 导入User组件,因为侧边栏可能会展示用户相关信息或其他导航链接等内容。

模板布局

  • 模板中是一个aside标签,内部包含三个User组件,使用在App组件中定义的flx类进行布局,使User组件在侧边栏中按一定方式排列。

User

xml 复制代码
<template>
    <div>
        User
    </div>
</template>

<script setup>

</script>


<!-- scoped css的作用域 -->
<style  scoped>
div{
    height:50px;
    width:50px;
    background-color: rgb(255, 127, 168);
    margin:5px;
}
</style>

模板内容

  • 模板中是一个div标签,用于显示用户相关的具体内容,比如用户头像、用户名等。

样式定义

  • 样式中设置div高度为 50px,宽度为 50px,背景颜色为rgb(255, 127, 168),外边距为 5px,用于展示用户信息的样式效果。

数据驱动

在 AppMain 模块下 , 我们添加一个打分的组件

xml 复制代码
<template>
   <main>
    Main
    <h1>你的评分是{{score}}</h1>
    <!-- 父子组件传递数据 -->
    <Rate :value="score"/>
    <Item/>
    <Item/>
   </main>
</template>

<script setup>
import Item from './Item.vue'
import Rate from './Rate.vue'
import {ref} from 'vue'
// 创建一个ref , 默认值为3
// 将数据从父组件传递给子组件 
const score = ref(3)
</script>

<style  scoped>
main {
   flex : 1;
   height: 500px;
   background-color: rgb(136, 111, 137);
}
</style>

Rate

xml 复制代码
<template>
    <div>
       {{rate}}
    </div>
</template>

<!-- vue 中script setup的作用:  -->
 <!-- 自动暴露组件的属性和方法。
 在 "script setup" 中定义的变量、函数等会自动暴露给模板使用,
 无需显式地通过return语句返回。 -->
<script setup>
import {ref,defineProps,computed} from 'vue'
//用于props业务消费数据 , 不是自身的数据 ,而是父组件绑定
//子组件和父组件不一定绑定的 , 哪里要用就往哪里绑定
let props = defineProps({
    //限制为Number类型
    value : Number
})
//组件自有的数据
let count =  ref(0)
let rate = computed(()=>"★★★★★☆☆☆☆☆".slice(5 - props.value, 10 - props.value))
</script>

<style scoped>

</style>
  • 从vue导入ref、defineProps、computed。使用defineProps定义value属性,限制其类型为Number,这个属性用于接收父组件(如AppMain)传递过来的评分数据,是组件间通信的重要方式。

巧妙设计评分

ini 复制代码
let rate = computed(()=>"★★★★★☆☆☆☆☆".slice(5 - props.value, 10 - props.value))

我的思路是 : 用一个长度为五颗星的尺子slice(5,10)置于"★★★★★☆☆☆☆☆"五颗空五角星上 , 之后在"★★★★★☆☆☆☆☆" 上移动 , 移动的距离是 : props.value

而props.value 是父组件 AppMain 传给子组件的值 , 通过 props 属性取出

组件通信总结

在这个示例中,我们展示了组件通信方式:

  1. Props 向下传递:

    • AppMain 向 Rate 传递初始评分
    • AppAside 向 User 传递用户数据

最佳实践建议

  1. 组件设计原则:

    • 单一职责原则:每个组件只做一件事
    • 高内聚低耦合:组件内部紧密相关,与外部关系简单
    • 合理的 props 设计:明确类型和默认值
  2. 可维护性:

    • 清晰的组件结构
    • 良好的文档注释
    • 一致的代码风格

总结

通过这个完整的示例,我们展示了如何:

  1. 将页面拆分为组件树
  2. 设计组件间的通信机制
  3. 实现响应式布局
  4. 创建可复用的组件
  5. 遵循 Vue 的最佳实践

组件化开发是 Vue 强大功能的基石,掌握组件树的设计和实现,能够显著提高开发效率和代码质量。

相关推荐
Csvn2 小时前
性能监控
前端
Csvn3 小时前
构建工具
前端
FRing033 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Java小卷4 小时前
JuanForm vs FormCreate!Vue3 表单引擎联动配置 PK!
vue.js·低代码
kyriewen5 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
IT_陈寒6 小时前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
工控丫丫6 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
jerrywus7 小时前
我用 GPT-6.1-sol 做了台会讲解的 3D 售货机:60 罐饮料,一口没喝上
前端·agent·claude
孟陬8 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
Zhao-Jichao8 小时前
AI Prompting for Everyone 课程笔记 - P17 图像生成 Imaging Generation
前端