class 6: vue.js 3 组件化开发
- 组件化开发实际上就是问题拆解,分而治之。将页面拆分为一个个小的功能块,每个功能块负责完成属于自己的独立功能,这使得整个页面的管理和维护就变得非常容易了
- 组件化可以简化开发进程,代码复用率更高,并有利于后期维护
- 使用
Vue.createApp()
函数时需要接收一个对象作为参数,改对象本质上就是一个组件,属于Vue.js 3的根组件。Vue.js 3的应用程序由一个个独立可复用的小组件构成,最终会被抽象成一颗组件树
接下来我们来注册一个全局组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<div class="comps-b">
<input type="text" v-model="message">
<h4> {{ message }}</h4>
</div>
<div class="comps-a">
<h4>{{ title }}</h4>
<p>{{ desc }}</p>
<button @click="btnClick">按钮单击</button>
</div>
</template>
<script src="./js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
message: 'Hello World',
title: '标题',
desc: '内容显示区域...'
}
},
methods: {
btnClick() {
console.log('按钮发生点击');
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
</html>
<style>
.comps-a,
.comps-b {
border: 1px solid #999;
}
</style>
- 在Vue.js 3中,注册组件分成如下两种:
- 全局组件:在任何其他组件中都可以使用的组件
- 局部组件:只有在注册的组件中才能使用的组件
注册全局组件需要通过全局创建的Vue实例(app)来使用app.component
方法,传入组件名称和组件对象来进行注册
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<div class="comps-b">
<input type="text" v-model="message">
<h4> {{ message }}</h4>
</div>
<!-- 使用全局组件 -->
<component-a></component-a>
</template>
<!-- component-a 全局组件的模板 -->
<template id="component-a">
<div class="comps-a">
<h4>{{ title }}</h4>
<p>{{ desc }}</p>
<button @click="btnClick">按钮单击</button>
</div>
</template>
<script src="./js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
message: "Hello World"
}
}
}
const app = Vue.createApp(App) // 创建一个Vue实例
// 用app注册一个component-a全局组件
app.component('component-a', {
template: '#component-a', // 引入第一步定义的模板
data() {
return {
title: '标题',
desc: '内容显示区域...'
}
},
methods: {
btnClick() {
console.log('按钮发生点击');
}
}
})
app.mount('#app')
</script>
</body>
</html>
<style>
.comps-a,
.comps-b {
border: 1px solid #999;
}
</style>
- 上面的例子中,首先将
class
为comps-b
的<div>
元素抽取到id
为component-a
的模板中;接着调用app.component
方法注册一个全局组件,该方法需要接收两个参数:全局组件名称和组件对象。组件对象中的template
属性绑定的是id
为component-a
的模板,该组件对象中定义了data
和methods
属性还定义了对应的变量和方法,可以提供给id
为component-a
的模板使用;然后把注册好的component-a
组件放到根组件的模板上使用,这样就完成了一个全局组件的注册和使用 - 这样实现的效果与最上面的全局组件实现的效果一致
也可以再提取出一个component-b
全局组件来
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<!-- 使用全局组件 -->
<component-b></component-b>
<component-a></component-a>
</template>
<!-- component-a 全局组件的模板 -->
<template id="component-a">
<div class="comps-a">
<h4>{{ title }}</h4>
<p>{{ desc }}</p>
<button @click="btnClick">按钮单击</button>
</div>
</template>
<!-- component-b 全局组件的模板 -->
<template id="component-b">
<div class="comps-b">
<input type="text" v-model="message">
<h4>{{ message }}</h4>
</div>
</template>
<script src="./js/vue.js"></script>
<script>
const App = {
template: '#my-app'
}
const app = Vue.createApp(App) // 创建一个Vue实例
// 用app注册一个component-a全局组件
app.component('component-a', {
template: '#component-a', // 引入第一步定义的模板
data() {
return {
title: '标题',
desc: '内容显示区域...'
}
},
methods: {
btnClick() {
console.log('按钮发生点击');
}
}
})
// 再注册一个component-b全局组件
app.component('component-b', {
template: '#component-b',
data() {
return {
message: "Hello World"
}
}
})
app.mount('#app')
</script>
</body>
</html>
<style>
.comps-a,
.comps-b {
border: 1px solid #999;
}
</style>
- 这也能实现相同的效果,这说明Vue.js 3中可以支持注册多个全局组件
组件是有命名规范的。推荐使用短横线隔开命名法(kebab-case),也就是a-b-c这种命名,不要出现大写字母
- 随着项目越来越复杂,我们需要采用组件化的方式进行开发,这意味着每个组件都会有自己的模板、脚本逻辑和样式等。虽然我们可以将它们抽离到单独的
JavaScript
、CSS
文件中,但它们依然会分离,而且引入全局作用域下的JavaScript
文件很容易出现命名冲突,也不支持ES6
语法的转换等 - 为了解决上面这些问题,Vue.js 3的开发模式推荐使用
.vue
单文件组件(Single-File Components, SFC
)来编写Vue.js组件,然后使用webpack、vite或Rollup等构建工具对其进行打包转换