1、组件的命名
- kebab-case(短横线)命名法:字母全小写且必须包含一个连字符;例:my-component-name
- PascalCase(帕斯卡)命名法:首字符大写;例:MyComponentName
在整个指引中,我们都使用 PascalCase 作为组件名的注册格式,这是因为:
- PascalCase 是合法的 JavaScript 标识符。这使得在 JavaScript 中导入和注册组件都很容易,同时 IDE 也能提供较好的自动补全。
- PascalCase 是合法的 JavaScript 标识符。这使得在 JavaScript 中导入和注册组件都很容易,同时 IDE 也能提供较好的自动补全。
< PascalCase /> 在模板中更明显地表明了这是一个 Vue 组件,而不是原生 HTML 元素。同时也能够将 Vue 组件和自定义元素 (web components) 区分开来。
在单文件组件和内联字符串模板中,我们都推荐这样做。但是,PascalCase 的标签名在 DOM 内模板中是不可用 ;
2、组件的介绍
组件是可复用的Vue实例;
组件注册类型:全局注册、局部注册;
2.1、全局组件
vue2 全局组件 介绍
使用Vue.component 来创建组件;
全局注册的组件,注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中;
也可在任意子组件中使用;
vue3 全局组件 介绍
使用 Vue 应用实例的 .component() 方法,让组件在当前 Vue 应用中全局可用。
.component() 方法可以被链式调用。
全局注册的组件可以在此应用的任意组件的模板中使用,包括子组件;
2.2、局部组件
vue2 局部组件 介绍
全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。 在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件
1、通过一个普通的 JavaScript 对象来定义组件;
2、在 components 选项中定义你想要使用的组件;
3、对于 components 对象中的每个 property 来说,其 property 名就是自定义元素的名字,其 property 值就是这个组件的选项对象;如下例3.2.1:component-a为自定义元素名,ComponentA 为组件的对象名;
4、局部注册的组件在其子组件中不可用;如需子组件A在子组件B中可用,需在子组件B的components选项中进行定义;具体参考下例3.2.1;
5、在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写;
vue3 局部组件 介绍
全局注册虽然很方便,但有以下几个问题:
- 全局注册,但并没有被使用的组件无法在生产打包时被自动移除 (也叫“tree-shaking”)。如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的 JS 文件中。
- 全局注册在大型项目中使项目的依赖关系变得不那么明确。在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性。
在使用 < script setup > 的单文件组件中,导入的组件可以直接在模板中使用,无需注册;参考4.2.2
没有使用 < script setup >,则需要使用 components 选项来显式注册;其他与vue2特点一致;
3、vue2组件注册
3.1、全局注册(所有页面均可直接使用,无需再引入)
3.1.1、全局注册组件在html的使用
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id='app'>
<component-a></component-a>
</div>
<script>
/*组件注册*/
Vue.component('component-a', {
template: `<div @click="changeHandle">{{msg}}</div>`,
data: function(){
return {
msg:'我是局部子组件'
}
},
methods:{
changeHandle(){
console.log('子组件点击事件');
},
}
})
/*创建vue实例*/
new Vue({
el: '#app',
data:{
count:0
},
mounted(){
console.log('mounted生命周期');
},
methods:{
/*方法*/
}
})
</script>
</body>
</html>
3.1.2、全局注册项目中使用
第一步,新建TabBar组件
src/components/TabBar.vue
<template>
<div class="footer-bar">
<div class="fotter-hFoot"></div>
<div class="footer-con">
<router-link to="/">首页</router-link>
<router-link to="/center">我的</router-link>
</div>
</div>
</template>
<script>
export default {
name:'TabBar'
}
</script>
第二步,main中全局注册组件
src/main.js文件
//main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
/*全局组件*/
import TabBar from './components/TabBar'
Vue.component('TabBar', TabBar)
/*vue实例化*/
new Vue({
router,
render: h => h(App)
}).$mount('#app')
第三步:页面中使用组件
src/view/index.vue页面中使用参考
<template>
<div class="index-main">
<P>我是首页</p>
<!-- 引入组件 -->
<TabBar index="1"></TabBar>
</div>
</template>
<script>
export default {
name: 'Home',
data(){
return {
title:null,
}
},
created(){
}
}
</script>
3.2、局部注册(使用页面需先引入才可使用)
3.2.1局部组件在html中引入及使用
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id='app'>
<component-a></component-a>
<component-b></component-b>
<left-text></left-text>
</div>
<script>
/*定义组件*/
var ComponentA = {
template: '<div>{{msg}}</div>',
data(){
return {
msg:'我是局部子组件'
}
}
};
var ComponentB = { /* ... */ };
/*创建vue实例*/
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB,
'left-text':{
template:`<div>left-text组件</div>`
}
},
data: {
count:0
}
})
</script>
</body>
</html>
局部注册的组件在其子组件中不可用,如果子组件想使用其他子组件,则需采用如下写法
var ComponentA = { /* ... */ };
var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
};
3.2.2局部组件项目中使用
通过 Babel 和 webpack 使用 ES2015 模块,那么代码可精简如下
/*index.vue页面*/
<template>
<div class="index-main">
<P>我是首页</p>
<!-- 使用局部组件 -->
<ComponentA></ComponentA>
</div>
</template>
<script>
import ComponentA from './components/ComponentA.vue'
export default {
name: 'Home',
components: {
ComponentA
},
data(){
return {
title:null,
}
},
created(){
}
}
</script>
4、vue3组件注册
4.1、全局注册
4.1.1、全局注册html中使用
<html>
<head>
</head>
<body>
<div id='app'>
<component-a></component-a>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const { createApp, ref } = Vue
/*创建vue实例*/
const app = createApp({
setup(){
const msg = ref('父组件');
return {
msg
}
}
})
/*全局注册组件*/
app.component('my-component',{
setup(){
const count = ref(0);
const msg = ref('全局子组件');
return{
count,
msg
}
},
template:`<div>{{msg}}:{{count}}</div>`,
})
/*挂载应用*/
app.mount('#app')
</script>
</body>
</html>
4.1.2、全局注册项目中使用
第一步:新建组件省略,参考vue2.0
第二步:全局组件注册
src/main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
const app = createApp(App)
/*全局组件注册*/
import TabBar from './components/TabBar'
import MyComponent from './components/MyComponent .vue'
/*可链式调用*/
app
.component('TabBar ',TabBar)
.component('MyComponent',MyComponent)
app.use(createPinia())
app.use(router)
app.mount('#app')
第三步:全局组件使用
<script setup lang="ts">
import { ref } from 'vue';
const count= ref(1)
</script>
<template>
<div class="home-main">
<MyComponent></MyComponent>
<TabBar></TabBar>
</div>
</template>
在 DOM 中书写模板 (例如原生 元素的内容),模板的编译需要遵从浏览器中 HTML 的解析行为。在这种情况下,你应该需要使用 kebab-case 形式
4.2、局部注册
4.2.1、局部注册html使用
<html>
<head>
</head>
<body>
<div id='app'>
<list-demo></list-demo>
<my-components></my-components>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const { createApp, ref } = Vue
/*创建组件MyComponents */
const MyComponents = {
setup(){
const msg = ref('MyComponents子组件');
return {
msg
}
},
template:`<div>{{msg}}</div>`
}
/*创建vue实例,创建list-demo组件并注册*/
const app = createApp({
components:{
'list-demo':{
setup(){
const msg = ref('局部子组件');
return{
msg
}
},
template:`<div>{{msg}}</div>`
},
'my-components': MyComponents //组件注册
},
setup(){
const msg = ref('父组件');
return {
msg
}
}
})
/*挂载应用*/
app.mount('#app')
</script>
</body>
</html>
4.2.2、局部注册项目中使用
使用 < script setup >
第一步:新建组件省略,参考vue2.0
第二步:页面注册及使用;在使用 < script setup > 的单文件组件中,导入的组件可以直接在模板中使用,无需注册
<script setup lang="ts">
import { ref } from 'vue';
/*局部组件引入,无需components注册*/
import MyComponent from '@/components/MyComponent.vue'
import MyComponentB from '@/components/MyComponentB.vue'
const count= ref(1)
</script>
<template>
<div class="home-main">
<MyComponent></MyComponent>
<MyComponentB></MyComponentB>
</div>
</template>
未使用 < script setup >
<script>
import { ref } from 'vue';
/*局部组件注册*/
import MyComponent from '@/components/MyComponent.vue'
import MyComponentB from '@/components/MyComponentB.vue'
export default{
components:{
MyComponent,
MyComponentB
},
setup(){
const count = ref(0);
function buttonClick(){
count.value++;
}
return{
count,
buttonClick
}
}
}
</script>
<template>
<div class="home-main">
<MyComponent></MyComponent>
<MyComponentB></MyComponentB>
</div>
</template>