为何我们不该使用 Vue.component
VueJS 作为一个框架最被我喜欢的一个功能是其被动的强制执行了良好的软件开发实践。
在设计上,它不强制要求任何编码格式或体系,不过它使编写正确代码变得容易了,借助 Vue 你也可以轻易做到。
一个示例是由 vue-loader 提供的 scoped
属性。
编写 仅 应用于但组件的样式通常是我们手动进行的。可以将你的组件包裹在一个类中,或者使用诸如 Atomic Design,BEM 或者 SMACSS 之类的命名约定。这样做并非不正确,不过这些操作都是手动进行的。而 scoped
这个关键字为你完成了与此相关的所有艰苦工作。
组件是另一个例子。大多数前端工程师(和 前端库)都认同组件是为了构建 UI 而存在的这一观点。归根结底,一个 VueJS 应用只是一堆组件的集合。
因此,你可能会问了:为何我们不应该使用 Vue.component 呢?
好吧...
使用 Vue.component 的组件是全局的
尽量避免全局变量. 自古以来,我们都在和全局变量作斗争。
全局组件的含义是 - 如果 组件 A 想要使用 组件 B,并且组件 B 是全局的,组件 B 可以放到 组件 A 的模板中,并且会正常渲染。除代码外,没有其他地方列出 组件 A 依赖于组件 B。
由于种种原因,全局并不是最佳选择,其中包括:
全局使重构代码变得更困难
如今,模块打包十分流行。这是非常好的设计。模块使我们可以方便的把代码到独立的文件中去。这不仅使我们的代码更 整洁独立,且更有利于重构。
那如何做呢?em...
我们所有的依赖都应该是显式的。 举个栗子,如果 模块 a 将要被删除了,而 模块 b 依赖 模块a,模块b 的功能被破坏了,然后打包工具将提示你。
这是一个多人协同开发的项目的重要功能,因为这降低了一个在模块中开发的心智负担。
如果文件依赖一个全局变量,那么你怎么知道这个全局变量是什么?一个对象?一个函数?一个类?这里并没有一个特别好的方法去获知它的情况,除非备注了,不过就算备注了,也不一定对。哪怕在某些时候它备注的是正确的,但这个变量也可能被覆写,因为 JavaScript 可以支持改写全局变量。
使用 Vue.component 与使用全局变量是一样的效果,并且存在着相同的问题。
<component-name>
可以是任何的组件:一个列表,弹窗,文本框,猫片等。使用 Vue.component 的话,找到 <component-name>
的实际位置的唯一办法是使用 IDE 的 查找全部
功能并检索 ComponentName
或 component-name
(以我之见)。
命名冲突
这里还有一个风险是组件名称已被使用。这将触发一个错误,导致你只能修改组件名称来解决。
In theory, you should be able to change the name of a component to whatever you wish based on where it is. This is possible if the component is defined as an explicit dependency, which I outline how to do below (“What To Use Instead” section).
从理论上讲,你应该能根据组件被使用的地方来改变组件为你需要的名称。如果将组件定义为显示的依赖,则有可能做到这一点,我在下面概述了应该如何做(“如何使用命名替代”小节)。
编码工具
本地定义的组件属性在自动完成工具中可见。
工具是编码的重要组成部分。对于使用 VSCode 的 Vue 用户来说,Vetur 为 .vue
组件提供了令人叹为观止的支持。
Veture 的功能之一就是自动补全组件属性,前提是组件在本地注册,而非全局注册。如果组件是全局的,将什么也看不到。
全局定义的组件,所需属性并未展示。
这很重要,因为这扮演了组件文档的另一层作用。如果你有 .NET 开发背景,你会知道有一个懂你所需的 IDE 是多么的方便。
对 Vue 组件来说,你可以获得同样的体验。你所需要做的就是在组件定义中添加注释:
然后就会在自动补全属性时传播。
请注意,下拉菜单中显示的是Prop提示示例。
使用什么来替代Vue.component
我喜爱带有提出问题和给出解决方案的技术文章。
使用它很容易. 你只需要为 全部 组件使用 本地注册。
这意味着替代它:
// ComponentName.vue
export default Vue.component("ComponentName", {...})
为如下:
// ComponentName.vue
export default {...}
因此无论何时只要你需要使用 ComponentName.vue
, 你都可以这样做:
// OtherComponentName.vue
import ComponentName from "./ComponentName.vue"
export default {
components: {
ComponentName
}
}
现在,全局组件的所有问题基本都得到了解决。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。