Vuejs:将代码分布在多个组件或所有组件中



所以我用Vue玩了很多游戏,现在我的应用程序变得很大了,我对如何组织它心存疑虑。

我了解组件,当您需要在同一页面上多次重复使用它们时,它们是有意义的,例如,在许多地方可能需要的"自定义选择框"组件。

但是那些只有一个实例的组件呢?示例:一个管理面板界面,它有3个区域:一个带有一些导航的侧边栏,一个带有可以根据导航中选择的内容进行编辑的内容的主区域,另一个带有与主区域相关内容的侧边栏。所有这些都需要是单独的组件吗?因为如果页面上只有一个实例,我看不出这样做有任何好处。另一方面,如果我把所有的代码都放在一个"应用程序"组件中,我可以简化一些代码(变量较少)

摘要-使用组件的典型原因:

  1. 可维护性
  2. 通过组件边界渲染性能
  3. 通过分块加载性能

如果您发现使用更少的组件可以提高可维护性,那也没关系。它很可能是您应用程序的正确设计。

详细版本如下。


使用组件的主要原因是为了提高可维护性。

在许多地方(如选择框)重用的组件显然比反复重复相同的代码更容易维护。然而,值得考虑的是为什么会这样。这不仅仅是因为重复会使更改所有选择框变得更加困难。使用组件的另一个关键好处是,额外的抽象级别可以减少心理开销。

比方说,有人试图维护代码,看到了这样的东西(伪代码):

<select-box :some-prop="blah">
<select-box-option v-for="something" />
</select-box>

很明显,这是一个select-boxselect-box所有血腥的实现细节都被隐藏起来了,我们不需要担心它们。通过查看道具、子组件和事件,我们可以快速推断出父组件和select-box之间来回的数据。这只是关注点的分离

这一好处也适用于不重复使用的组件。让我们以侧边栏为例。我们可以在我们的主要组件的模板中看到这一点:

<nav-sidebar @navigate="onNavigate" />

该组件的名称使我们能够快速将其识别为侧边栏。如果我们当前的任务不涉及侧边栏,那么我们可以跳过模板的那一部分。由于代码已经转移到另一个文件,我们很容易确定代码的哪些部分是侧边栏的一部分,哪些部分不是。

在这个例子中,nav-sidebar没有任何道具,只有一个事件。从中我们可以开始得出一些关于这些组件如何相互作用的结论。看起来nav-sidebar不需要从主组件传递任何东西,它可以非常愉快地独立运行。如果我们需要调试数据以另一种方式流动的问题,我们几乎肯定会从onNavigate开始。

如果所有的东西都被拼凑成一个很大的组成部分,我们就不能很快开始进行这样的扣除。

当然,这可能是我们的扣除是错误的。可能是nav-sidebar做了一些涉及$parent的可怕事情来从其父组件获取数据。然而,这恰恰说明了为什么使用这种技术被认为是不好的做法。可维护代码应该允许开发人员根据看起来已经到位的抽象得出合理的结论。

但反过来也有可能走得太远。

一个好的抽象可以通过隐藏标签后面的细节来释放一些心智能力。一个糟糕的抽象会将你想要看到的代码隐藏在一些间接的后面,从而增加心理开销。再加上命名的困难和额外的粘合代码的负担,你最好放弃额外的层,让所有东西都保持内联。

另一件可能出错的事情是以错误的方式拆分组件。分离关注点需要对这些关注点进行干净的分区。把东西稍微分开,你最终会发现一个问题分散在多个组件上,由此产生的混乱通常比你根本不想把东西分开的情况更糟。

Vue允许您以多种方式分割JavaScript代码,组件只是其中之一。单独的.js文件、插件、过滤器、Vuex、mixin等。有几个选项可供选择。

另一方面,模板只能通过使用组件来真正拆分。如果你想把一个巨大的模板分解成更易于管理的块,那么组件实际上是唯一的方法。

这就引出了使用组件的另一个关键原因。

一个模板被编译成一个render函数。当render函数运行时,它会注册反应依赖关系,就像计算属性一样。如果这些依赖项中的任何一个发生更改,它将触发重新渲染。这将再次运行整个render函数。即使这不会导致对DOM的任何更改,也需要生成所有相关的VNode,并且困难算法需要检查所有这些VNode。

组件边界也是渲染边界。每个组件根据其依赖项是否已更改来决定是否进行渲染。

因此,以nav-sidebar为例,假设nav-sidebar发生了一些变化,因此需要进行渲染更新。如果nav-sidebar是一个单独的组件,那么它只需要为该组件运行template/render函数。如果我们将所有nav-sidebar代码捆绑到主模板中,那么我们将不得不重新呈现所有内容。

Vue还支持延迟加载组件,以减少页面的初始加载时间。其想法是,许多应用程序都有与大多数用户无关的大部分,例如管理界面。您可以将组件拆分为块,并在需要时下载块,而不是承担下载所有这些组件的开销。这通常通过Vue路由器配置来实现。

撇开阻塞不谈,使用路由器的典型方式是为不同的页面提供单独的组件。虽然在理论上,可以对所有路线使用相同的组件,但这不太可能导致更易于维护的东西。我想补充的是,"页面">的定义在这里有点模糊,但在大多数应用程序中,很清楚是什么构成了不同的页面,从而产生了不同的组件。

如果不提及测试,任何关于创建代码块的大部头都是不完整的。单元测试应该被认为是一种重用形式,在这方面是一种特别极端的形式。测试有一种无情的技巧,可以揭露隐藏在你认为漂亮、干净的设计背后的意大利面条的混乱。我不打算对测试发表意见,但我只想说,除非你把东西分解成合适的单元,否则你将无法编写单元测试。

组件的另一个关键特性是它有自己的一组属性。它自己的CCD_ 18和它自己的计算性质。这听起来很明显,但当您考虑通过v-for循环时,它会变得很重要。

<div v-for="item in items">...</div>

上面的示例使用内联元素而不是组件。任何州都只能依靠父级生存。每个循环项都需要保持该状态,因此我们最终可能会得到多个数组来保持状态的不同方面。使用循环时,计算属性同样难以实现。我们通常最终会使用以下方法:

<div v-for="item in items" :class="getClassesFor(item)">...</div>

现在考虑组件版本:

<my-component v-for="item in items" :item="item" />

每个CCD_ 20可以保持其自己的状态。例如,假设my-component具有扩展/折叠功能。现在可以将其存储在每个实例中的本地data属性中。同样,每个实例都有自己的计算属性。

可以说,这只是重用,因为v-for创建了多个实例。然而,鉴于我们专门引入了一个新组件,只是为了提供一种形式的属性范围,我认为值得特别提及。

我个人喜欢有3种类型的组件。

  1. 可重用系统组件。这些用于常规布局、自定义按钮、自定义选择框。。。它们可以在代码中多次重复使用,并且用途非常广泛。

  2. 页面/视图组件。管线通常会敷设到特定零部件。该组件是多个组件的某种组合。这种区别可以快速识别应用程序的"页面"。

  3. 逻辑划分。这些是最难找到的。我倾向于孤立彼此无关的事物。例如,页脚可能不可重用,但对页脚的修改应该只涉及页脚。其他示例包括导航栏、菜单、管理员的每个部分。这些组件应该尽可能地可重复使用,但有时它们是特定的。

另一个例子:注释系统。"注释"将是类型3的组成部分。"注释线程"显示将是使用"注释"组件的类型3的另一个组件。将存在一个用于评论线程主题的页面,并且该页面的类型为2。注意,类型3和类型2的每个组件可以使用其他类型的其他组件。如果我想更改评论线程的显示安排,我只需要更改"评论线程"组件。

Vue组件不仅用于重用。您可以将组件拆分为逻辑块。例如SPA。您可以基于vue组件创建网格。

以下是为什么即使只使用一次也需要拆分代码的原因

有数百或数千行代码,毫无疑问将代码拆分到不同的文件中有助于使其更易于管理。尽管如此,如果分手不是事先想好的。

代码分割得越多,就越清晰。

它不仅适用于VueJS,而且几乎适用于编程语言。

最新更新