学完互动教程,已经有个基本印象,再看看文档,基础部分有涉及了,所以看深入组件那部分文档
注册
全局注册
可以使用 Vue
应用实例的 .component()
方法,让组件在当前 Vue
应用中全局可用
1 | import { createApp } from 'vue' |
如果使用单文件组件,你可以注册被导入的 .vue
文件:
1 | import MyComponent from './App.vue' |
.component()
方法可以被链式调用:
全局注册的组件可以在此应用的任意组件的模板中使用
局部注册
全局注册的问题
- 打包的时候,没有用到的组件也不会被移除(tree-shaking)
- 全局注册在大型项目中使项目的依赖关系变得不那么明确
局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。它的优点是使组件之间的依赖关系更加明确,并且对 tree-shaking
更加友好
1 | <script> |
昨天学的互动教程里的写法就是局部注册的方式
组件名格式
使用 PascalCase
作为组件名的注册格式
PascalCase
就是大驼峰的命名
PascalCase
是合法的JavaScript
标识符。这使得在JavaScript
中导入和注册组件都很容易,同时IDE
也能提供较好的自动补全。<PascalCase />
在模板中更明显地表明了这是一个Vue
组件,而不是原生HTML
元素。同时也能够将Vue
组件和自定义元素(web components)
区分开来
这两点确实有道理
透传 Attributes
Attributes 继承
“透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props
或 emits
的 attribute
或者 v-on
事件监听器。最常见的例子就是 class
、style
和 id
。
当一个组件以单个元素为根作渲染时,透传的 attribute
会自动被添加到根元素上
表述有点书面化,但是看完例子后非常容易理解
1 | <!-- 比如 <MyButton> 的模板是下面这样的 --> |
这里有个问题,如果是id
怎么办,也是直接加上去?
打开创建的前几天创建的Vue
的Demo
工程
1 | # 报权限错误可以加sudo |
App.vue
是 Helloworld.vue
的父组件,而且Helloworld.vue
满足单个元素作为根渲染
App.vue 添加id属性
1 | ... |
Helloworld.vue
1 | ... |
最终结果显示了父组件
去掉父组件里的id
,则显示子组件的id
小结:
Attribute
透传: 子组件根节点加样式,一般适用于class
,id
,style
。其中class
是追加的,而id
是使用父组件替换掉子组件
依赖注入
应用层 Provide
1 | import { createApp } from 'vue' |
Prop 逐级透传问题
通常情况下,当我们需要从父组件向子组件传递数据时,会使用 props
。想象一下这样的结构:有一些多层级嵌套的组件,形成了一棵巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。在这种情况下,如果仅使用 props
则必须将其沿着组件链逐级传递下去,这会非常麻烦:
注意,虽然这里的 <Footer>
组件可能根本不关心这些 props
,但为了使 <DeepChild>
能访问到它们,仍然需要定义并向下传递。如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”,显然是我们希望尽量避免的情况。
provide
和 inject
可以帮助我们解决这一问题
示例图已经比较清楚说明了Provider
和Inject
的用途了
完整示例
App.vue
1 | <script> |
Child.vue
1 | <script> |
GrandChild.vue
1 | <script> |
异步组件
基本用法
在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件。Vue
提供了 defineAsyncComponent
方法来实现此功能:
1 | import { defineAsyncComponent } from 'vue' |
导入单文件组件
1 | import { defineAsyncComponent } from 'vue' |
最后得到的 AsyncComp
是一个外层包装过的组件,仅在页面需要它渲染时才会调用加载内部实际组件的函数。它会将接收到的 props
和插槽传给内部组件,所以你可以使用这个异步的包装组件无缝地替换原始组件,同时实现延迟加载。
加载与错误状态
1 | const AsyncComp = defineAsyncComponent({ |
最后的感想
Vue
的文档很清晰,导致这部分大多数是”转译”下原来的文档,价值寥寥,只能算熟悉框架了…..
耐心点,慢慢来