上一节实验中,我们大概了解了一下组件的基础,这一节实验我们要深入组件注册。
组件名字
我们在注册组件的时候,我们都会给组件起一个名字,就好像我们人的名字一样。需要注意的是,我们的组件名字是有一些规范的,一般这种单文件组件,我们强烈推荐使用字母全小写且必须包含一个连字符,全部小写字母,单词使用中华线 - 隔开。
例如我们在 src/main.js 下注册的全局组件:
app.component('content-box', {
template: `<div>
这是插槽内容
<slot></slot>
</div>`
})
组件名字规范
在字符串模板或单个文件组件中定义组件时,定义组件名的方式有两种:
使用kebab-case
app.component('content-box', {
template: `<div>
这是插槽内容
<slot></slot>
</div>`
})
当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如:
<template>
<div class="template-m-wrap">
<content-box> Something bad happened. </content-box>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
searchText: "",
};
},
};
</script>
使用 PascalCase
app.component('contentBox', {
template: `<div>
这是插槽内容
<slot></slot>
</div>`
})
当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <contentBox> 和 <content-box> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的:
<template>
<div class="template-m-wrap">
<content-box> Something bad happened. </content-box>
<contentBox>Something bad happened.</contentBox>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
searchText: "",
};
},
};
</script>
全局注册
想我们在 src/main.js 实现组件的注册:
import { createApp } from 'vue/dist/vue.esm-bundler.js'
import App from './App.vue'
import router from './router'
import store from './store'
let app = createApp(App)
app.use(store).use(router).mount('#app')
app.component('button-counter', {
template: `<button @click="count">{{counter}}</button>`,
data() {
return {
counter: 0,
}
},
methods: {
count() {
this.counter++
}
}
})
// 我们再来定义一个全局组件
app.component('blog-title', {
props: {
title: {
type: String,
default: ''
}
},
template: `<div>
<h4>{{title}}</h4>
<button @click="emitFn">changeSize</button>
</div>`,
methods: {
emitFn() {
this.$emit('change-size', 10)
}
},
emits: ['change-size']
})
app.component('custom-input', {
props: ['modalVal'],
template: `
<input v-model="value">
`,
computed: {
value: {
get() {
return this.modalVal
},
set(val) {
this.$emit('update:modalVal', val)
}
}
}
})
app.component('content-box', {
template: `<div>
这是插槽内容
<slot></slot>
</div>`
})
以上组件都是全局注册组件,我们在使用的时候如下:
<template>
<div class="template-m-wrap">
<content-box> Something bad happened. </content-box>
<blog-title title="这是博客标题"></blog-title>
<custom-input v-model="searchText"></custom-input>
</div>
</template>
<script>
export default {
name: "TemplateM",
data() {
return {
searchText: "",
};
},
};
</script>
查看浏览效果如下:
局部注册
全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。
你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
}
// ...
}
接下来我们就来实现一个局部组件的注册:
我们现在在 src/views 新建一个组件 TestCom.vue:
<template>
<div class="test-com-wrap">
局部组件
</div>
</template>
<script>
export default {
name: 'TestCom',
}
</script>
然后导入到 src/views/TemplateM.vue 组件里面注册:
<template>
<div class="template-m-wrap">
<test-com></test-com>
</div>
</template>
<script>
import TestCom from './TestCom'
export default {
name: "TemplateM",
components: {
TestCom
},
data() {
return {
searchText: "",
};
},
};
</script>
我们查看浏览效果如下: