小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
1. 组件的名称
在通过 app.component 注册一个组件时,第一个参数是组件的名称,定义组件名的方式有两种:
-
使用
kebab-case(短横线分隔命名)-
app.component('my-component-name', { /* ... */ }) -
当使用
kebab-case(短横线分隔命名)定义一个组件时,你也必须在引用这个自定义元素时使用kebab-case,例如<my-component-name>;
-
-
使用
PascalCase(首字母大写命名)-
app.component('MyComponentName', { /* ... */ }) -
当使用
PascalCase(首字母大写命名)定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说<my-component-name>和<MyComponentName>都是可接受的。但要注意,直接在DOM(而不是在字符串模板或单文件组件中)中使用时只有kebab-case是有效的。<div id="app"></div> <template id="my-app"> <!-- kebab-case 方式使用,没有问题 --> <component-c></component-c> <!-- 直接在 DOM 中,以 PascalCase 方式使用,会解析失败: [Vue warn]: Failed to resolve component: componentc --> <ComponentC></ComponentC> </template> <template id="component-c"> <h2>ComponentC</h2> </template> <script src="./js/vue.js"></script> <script> const App = { // template: '#my-app' // 在字符串模板中,以 PascalCase 方式使用,可以正常解析 template: `<ComponentC></ComponentC>` }; const app = Vue.createApp(App) // PascalCase 方式注册 app.component('ComponentC', { template: '#component-c' }) app.mount('#app'); </script>
-
总之,不管是采用 kebab-case 方式还是 PascalCase 方式命名组件,我们在使用组件时一般都是通过 kebab-case 的方式引用的(在命名组件的时候则经常会用 PascalCase 方式命名)。而当直接在 DOM 中(而不是在字符串模板或单文件组件中)使用一个组件时,推荐遵循 W3C 规范来给自定义标签命名:
- 全部小写
- 有多个单词时,多个单词之间用连字符符号(
-)连接
也就是采用 kebab-case 方式命名了。这样会帮助我们避免与当前以及未来的 HTML 元素发生冲突。
2. 注册局部组件
开发中,注册全局组件的情况较少,我们更多的是注册局部组件。
- 全局组件往往是在应用程序一开始就会完成全局注册,这就意味着如果某些(全局)组件我们并没有用到,也会被注册:
- 比如我们注册了三个全局组件:
ComponentA、ComponentB和ComponentC; - 而在开发中我们只使用了
ComponentA和ComponentB,即ComponentC没有被用到,但是我们已经在全局注册了ComponentC,这就意味着类似于Webpack这种打包工具在打包我们的项目时,依然会对ComponentC进行打包; - 这样最终打包出的
JavaScript包就会有关于ComponentC的内容,这就会增加包的大小,导致用户下载的JavaScript的无谓的增加。
- 比如我们注册了三个全局组件:
- 所以在开发中我们通常采用局部注册的方式注册组件:
- 局部注册就是在我们需要使用到的组件中,通过
components属性选项来进行注册; - 比如之前的
App组件中,我们有data、computed和methods等选项了,其实还可以有一个components选项; - 这个
components选项对应的是一个对象,对象中的键值对是“组件的名称: 组件对象”;
- 局部注册就是在我们需要使用到的组件中,通过
前面我们讲了全局注册组件的方式,比如全局注册一个 ComponentA 组件:
<div id="app"></div>
<template id="my-app">
<component-a></component-a>
</template>
<template id="component-a">
<h2>ComponentA</h2>
</template>
<script src="./js/vue.js"></script>
<script>
const App = {
template: '#my-app'
};
const ComponentA = {
template: '#component-a'
};
const app = Vue.createApp(App);
app.component('ComponentA', ComponentA);
app.mount('#app');
</script>
现在,如果我们希望注册一个 ComponentY 组件,它只在组件 ComponentX 中可以使用,那么就可以在 ComponentX 组件中局部注册 ComponentY 组件了。比如在 App 组件中局部注册 ComponentA 组件:
<div id="app"></div>
<template id="my-app">
<component-a></component-a>
</template>
<template id="component-a">
<h2>ComponentA</h2>
</template>
<script src="./js/vue.js"></script>
<script>
const ComponentA = {
template: '#component-a'
};
const App = {
// 在 components 选项中局部注册组件
components: {
// key:组件名称
// value:组件对象
// key: value
// ComponentA: ComponentA
// ES6 增强的对象--属性值简写:
ComponentA
},
template: '#my-app'
};
const app = Vue.createApp(App);
app.mount('#app');
</script>
这样一来,ComponentA 组件目前就只能在 App 组件中使用了。其它组件中如果也想使用这个 ComponentA 组件,也得先在它们的 components 选项中注册 ComponentA 组件才行。
关于组件化的更多内容我们会在脚手架中再讲,因为脚手架中我们会使用一个个独立的文件编写 Vue 相关的代码,那时代码结构会更加清晰。