gitHub地址:https://github.com/huangpna/vue_learn/example里面的lesson07
一 定义组件
1、 组件名:
在注册组件的时候我们始终需要给它一个名字,比如在全局注册的时候我们已经看到了。
Vue.component('my-component-name',{
/**/
});
该组件名就是 Vue.component
的第一个参数。
规范:我们强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符),这会帮助你避免和当前以及未来的 HTML 元素相冲突。
2、组件名大小写:
定义组件名的方式有两种:
使用kebab-case
Vue.component('my-component-name', { /* ... */ })
当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>
。
使用 PascalCase
Vue.component('MyComponentName', { /* ... */ })
当使用 PascalCase (驼峰式命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name>
和 <MyComponentName>
都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。
kebab-case和PascalCase的具体区别还是有些不太明白,除了书写方式的不同外;之后会再写一遍文章重新整理。
二 全局注册
举例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index1</title> </head> <body> <div id="app1"> <my-component-name1></my-component-name1> <my-component-name2></my-component-name2> <my-component-name3></my-component-name3> </div> </body> <script src="../js/vue.min.js"></script> <script> Vue.component('my-component-name1', {template:'<div>组件一</div>'}); Vue.component('my-component-name2', {template:'<div>组件二</div>'}); Vue.component('my-component-name3', {template:'<div>组件三</div>'}); new Vue({ el:'#app1' }) </script> </html>
这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue
) 的模板中。
注意:在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。
缺点:全局注册往往是不够理想的,比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。
三 局部注册
举例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index2</title> </head> <body> <div id="app2"> <component-a></component-a> <component-b></component-b> </div> </body> <script src="../js/vue.min.js"></script> <script> var componentA = { template:'<div>组件1</div>' }; var componentB = { template:'<div>组件2</div>' }; new Vue({ el:'#app2', components:{ //通过components来定义你想到的组件 'component-a':componentA, // 属性名:自定义元素的名字 属性值:组件的选项对象 'component-b':componentB } }) </script> </html>
注意:局部注册的组件在其子组件中不可用,例如:如果你希望 ComponentA
在 ComponentB
中可用,则你需要这样写:
var componentA = { template:'<div>组件1</div>' }; var componentB = { template:'<div>组件2</div>', components:{ 'component-a':componentA } }; new Vue({ el:'#app2', components:{ 'component-b':componentB } })
或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
},
// ...
}
注意:在 ES2015+ 中,在对象中放一个类似 ComponentA
的变量名其实是 ComponentA: ComponentA
的缩写
三 模块系统
1、在模块系统中局部注册
如果你使用了诸如 Babel 和 webpack 的模块系统,在这些情况下,我们推荐创建一个 components
目录,并将每个组件放置在其各自的文件中。
然后你需要在局部注册之前导入每个你想使用的组件。例如,在一个假设的 ComponentB.js
或 ComponentB.vue
文件中:
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
2、基础组件的自动化全局注册
可以你的很多组件都只包含了一个输入框或者按钮的元素,是相对通用的,我们有时候会把它们称为基础组件,它们会在各个组件中被频繁的用到。
所以会导致很多组件里都会有一个包含基础组件的长列表:
import BaseButton from './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput from './BaseInput.vue'
export default {
components: {
BaseButton,
BaseIcon,
BaseInput
}
}
而只是用于模板中的一小部分:
<BaseInput v-model="searchText" @keydown.enter="search" /> <BaseButton @click="search"> <BaseIcon name="search"/> </BaseButton>
幸好如果你使用了 webpack (或在内部使用了 webpack 的 Vue CLI 3+),那么就可以使用 require.context
只全局注册这些非常通用的基础组件。这里有一份可以让你在应用入口文件 (比如 src/main.js
) 中全局导入基础组件的示例代码:
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
const requireComponent = require.context(
// 其组件目录的相对路径
'./components',
// 是否查询其子目录
false,
// 匹配基础组件文件名的正则表达式
/Base[A-Z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
// 获取组件配置
const componentConfig = requireComponent(fileName)
// 获取组件的 PascalCase 命名
const componentName = upperFirst(
camelCase(
// 剥去文件名开头的 `./` 和结尾的扩展名
fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
)
)
// 全局注册组件
Vue.component(
componentName,
// 如果这个组件选项是通过 `export default` 导出的,
// 那么就会优先使用 `.default`,
// 否则回退到使用模块的根。
componentConfig.default || componentConfig
)
})
记住全局注册的行为必须在根 Vue 实例 (通过 new Vue
) 创建之前发生。
先这样,还有一些不明白的,但是因为现在没有搭建vue+webpack框架,暂时无法验证,后续搭建之后一一验证。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构