没时间学 Vue (11) —— 组件(一):最基本的单文件组件

本文解析Vue组件的本质,从组件注册、单文件组件到复用与结构,引导读者理解组件在项目中的关键作用并实战拆分技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇开始会涉及到 Vue (以及其他前端框架)中最为滥用和难以拿捏的内容 —— 组件(Component)。

Vue 官方相关的说明资料如下,不过我们还是会基于 “功利的实用主义” 跳着来讲。

此外,也推荐几个延伸阅读的资料,有时间的时候慢慢看。

 

1、组件是什么?


抛开各种枯燥的官方解释,我们先从几个例子入手来直观地理解组件是什么。

1)不使用 Vue 脚手架时的编码方式:

我们在 《没时间学 Vue (9) —— 小结(一):绑定 + 渲染 + 事件处理,你已经很厉害了》这一篇里,实现了下面这样的复杂功能。

我们当时把 HTML 元素和控制用的 JavaScript 代码都写在一个 HTML 文件中,大概是这样的。

2)使用 Vue 脚手架之后的编码方式:

而我们在 《没时间学 Vue (10) —— 实践(一):第一个 Vue 项目》中使用的 @vue/cli 脚手架创建的项目中,则是这个样子的:

简单跟不使用 Vue 脚手架的编码方式做个比较,我们很容易就会发现,App.vue 其实就是个 “页面级” 的组件,整个页面中的有效内容其实都在 App.vue 里面。

要是我们用脚手架来改造的话,大概会是下面这个样子的:

3)组件嵌套其他组件

我们再来细看组件 App.vue,你会发现它还嵌套使用了另一个组件 HelloWorld.vue。

至此,我们可以脑补出整个程序运行时,页面大概是这样的构成(把各个组件中的 template 展开):

跟 HTML 元素的树状结构是不是很像?

套用 Vue 官网的描述,就是 “通常一个应用会以一棵嵌套的组件树的形式来组织”:

Component Tree

4)多页面复用的组件

我们在《没时间学 Vue (5) —— 绑定(四):面向单选、复选和选择框的 v-model》等章节里,介绍了各种 HTML 原生的选择控件,这些控件可以在各个页面中重复使用。

除了这些原生的控件,还有很多各式各样、基础的、在各个页面之间复用的组件,比如说:(选自 Element 组件库

借助统一的组件技术,我们可以很方便的在代码中使用它们。

<el-switch v-model="switchValue" active-text="按月付费" inactive-text="按年付费">
</el-switch>

<el-date-picker v-model="dateValue" type="date" placeholder="选择日期">
</el-date-picker>

5)组件是什么

Vue 官网也没有给出明确的定义,所以这个问题某种程度来说只能意会、不可言传。

简单来看可以这么理解,组件就是为了实现特定功能的一组 HTML 元素和其他组件的封装

既可能是可以被广泛复用的 “简单而基础的” 组件(比如:日期选择组件),也可能是为了实现特定功能的某个页面(比如:我们在之前做的模拟商城页面)。

跨度如此之大,导致组件的切分变成了一个非常“艺术”的事情 —— 就像微服务的切分粒度一样,没有最好、只有合适

但是合适是什么?没有显而易见的标准,制约条件倒是多如牛毛,比如说:当前的产品定位和业务内容、公司 and/or 项目方针、项目人员能力、架构师个人偏好等等。

还是以 1)中的模拟购物车功能为例,你觉得要切分成几个组件呢?需不需要再细分呢、或者合并呢?

对于新手来说,最简单的做法是:

  • 如果项目中有指导原则的话,遵循项目的指导原则
  • 如果项目中没有指导原则的话,尽量按照高内聚、低耦合的原则来切分组件,保证每个组件功能和责任明确,而且组件尽量少、组件之间的嵌套关系简单易懂

《深入理解Vue.js实战》4.4 组件的自我修养 等资料中也有各种经验介绍,可以参考。

 

2、最基本的组件怎么写


接下来,我们以偏重单文件组件(而跳过部分基础的组件内容)的方式,来看看如何写一些最基本的组件。

以 App.vue 为例 —— 这个组件就是一个 “单文件组件”,一个 vue 文件代表了一个完整的组件 —— 很容易发现单文件组件的 Vue 文件是由这么三大部分组成的:

由于 Vue 脚手架生成的两个组件都不是最简单的形式,所以我们还得换另一个例子。

我们在 《没时间学 Vue (2) —— 绑定(一):简介》中,做了一个非常简单的画面,就是显示这么一行字:

    <div id="app">
      <div>{{message}}</div>
    </div>
    <script>
      var app = new Vue({
        el: "#app",
        data: {
          message: "没时间学 Vue",
        },
      });
    </script>

如果要应用到 Vue 脚手架生成的项目中的话,我们会把组件 App.vue 改成大概这个样子的。

<template>
  <div id="app">
    <div>{{ message }}</div>
  </div>
</template>

<script>
export default {
  name: "App",
  data: function () {
    return {
      message: "没时间学 Vue"
    }
  }
};
</script>

<!-- 没有特殊的样式 -->
<style>
</style>

映射关系是这样的:(再具体一点儿的可以参照 https://vue-loader.vuejs.org/zh/spec.html

注意,data 属性在组件中必须写成函数,否则运行的时候会报以下错误、强制你把 data 改成函数。

(准确说是运行前使用 ESLint 进行静态检查的时候,报出了这个错误)

至于为什么要把 data 属性做成函数呢?主要是为了复用组件时,各个组件的数据能安全地相互隔离。

比如说,画面上有 2 个日期选择组件分别用来指定开始日期和结束日期。如果不把 data 做成函数的话,那么这 2 个日期选择组件的 data 就是完全一样的,任何一个修改了会影响到另一个。

Vue 官网的解释《data 必须是一个函数》读起来有些绕口,不过里面的例子却是非常生动。

<script> 中除了 data 属性之外,我们之前用过的 methods 属性也可以照搬过来。

(其他的更多属性可以参照 https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E6%95%B0%E6%8D%AE,暂时先跳过)

另外,我们有意绕开了 <style> 样式定义这部分,但是相关的基础知识还是要学习学习的,各个项目中都会涉及到画面布局和显示效果的问题。

有时间的时候,推荐至少翻一翻 CSS 速查手册、 MDN CSS 教程 中关于选择器和布局的部分,最好还能在 freeCodeCamp 中动手试一试。

对了,非常推荐为每一个组件的根元素(也就是 <template> 中的第一个元素)设置一个全局唯一的 id 或者 class

这样比较容易实现 “有作用域的 CSS”,避免多个组件之间的样式冲突。

 

3、思考题


本篇的思考题,就把之前做的这个画面,改成单文件组件吧 —— 先热热身,为后面更深入的组件运用方式做准备。

有时间有余力的话,也可以考虑和尝试以下拆分成多个组件。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值