组件化编程
2023年11月30日大约 7 分钟约 1476 字
基本说明
- 在大型应用开发的时候,页面可以划分成很多部分,往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
- 但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发(如图)
- 组件(Component) 是 Vue.js 最强大的功能之一(可以提高复用性[1.界面2.业务处理])
- 组件也是一个Vue实例,也包括∶ data、methods、生命周期函数等
- 组件渲染需要 html模板,所以增加了template 属性,值就是 HTML 模板
- 对于全局组件,任何 Vue 实例都可以直接在 HTML 中通过组件名称来使用组件
- data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据
应用实例
需求如下, 点击一个按钮, 可以显示点击的次数
普通方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<!--非组件化方式-普通方式-->
<button v-on:click="click1()">点击次数= {{count}} 次【非组件化方式】</button><br/><br/>
<!--需求是,有多个按钮,都要进行点击统计
1. 其实三个按钮界面其实一样, 但是目前我们都重新写了一次, 复用性低
2. 点击各个按钮的业务都是对次数+1, 因此业务处理类似,但是也都重新写了一个方法, 复用性低
3. 解决===> 组件化编程
-->
<button v-on:click="click2()">点击次数= {{count2}} 次【非组件化方式】</button><br/><br/>
<button v-on:click="click3()">点击次数= {{count3}} 次【非组件化方式】</button><br/><br/>
</div>
<script>
new Vue({
el:"#app",
data:{
count:10,
count2: 10,
count3: 10
},
methods:{//methods属性, 可以定义相应的方法
click1(){
this.count++;
},
click2() {
this.count2++;
},
click3() {
this.count3++;
}
}
})
</script>
</body>
</html>
问题分析
- 点击次数会共享
- 如果要解决, 需要我们定义不同的点击次数变量(比如 count、count2、count3 等)来记录不同
- 复用性差
全局组件方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<h1>组件化编程-全局组件</h1>
<!--使用全局组件-->
<counter></counter>
<br>
<counter></counter>
<counter></counter>
<counter></counter>
</div>
<div id="app2">
<h1>组件化编程-全局组件2</h1>
<counter></counter>
<br>
<counter></counter>
<counter></counter>
<counter></counter>
</div>
<script>
//1、定义一个全局组件, 名称为 counter
//2. {} 表示就是我们的组件相关的内容
//3. template 指定该组件的界面, 因为会引用到数据池的数据,所以需要是模板字符串
//4. 说明: 要把组件视为一个Vue实例,也有自己的数据池和methods
//5. 说明: 对于组件,我们的数据池的数据,是使用函数/方法返回[目的是为了保证每个组件的数据是独立], 不能使用原来的方式
//6. 这时我们达到目前,界面通过template实现共享,业务处理也复用
//7. 全局组件是属于所有vue实例,因此,可以在所有的vue实例使用
Vue.component("counter",{
template:`<button v-on:click="click()">点击次数= {{count}} 次【全局组件化方式】</button>`,
data(){//这里需要注意,和原来的方式不一样!!!!
return{
count:10
}
},
methods:{
click(){
this.count++;
}
}
})
//创建vue实例,必须有
let vm = new Vue({
el:"#app",
})
let vm2 = new Vue({
el:"#app2",
})
</script>
</body>
</html>

局部组件方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<h1>组件化编程3-局部组件</h1>
<!--使用局部组件 ,该组件是从挂载到app的vue中的-->
<my_counter></my_counter><br/>
<my_counter></my_counter><br/>
<my_counter></my_counter><br/>
</div>
<div id="app2">
<h1>组件化编程3-局部组件2</h1>
<!--使用局部组件 ,该组件是从挂载到app的vue中的-->
<lzw_counter></lzw_counter><br/>
<lzw_counter></lzw_counter><br/>
<lzw_counter></lzw_counter><br/>
</div>
<script>
//定义一个组件, 组件的名称为 buttonCounter
//1. 可以把常用的组件,定义在某个commons.js中 export
//2. 如果某个页面需要使用, 直接import
const buttonCounter = {
template:`<button v-on:click="click()">点击次数= {{count}} 次【局部组件化方式】</button>`,
data(){//这里需要注意,和原来的方式不一样!!!!
return{
count:10
}
},
methods:{
click(){
this.count++;
}
}
}
//创建vue实例,必须有
let vm = new Vue({
el:"#app",
components:{//引入/注册某个组件, 此时my_counter就是一个组件, 是一个局部组件,他的使用范围在当前vue
'my_counter':buttonCounter
}
})
let vm2 = new Vue({
el:"#app2",
components:{//引入/注册某个组件, 此时lzw_counter就是一个组件, 是一个局部组件,他的使用范围在当前vue
'lzw_counter':buttonCounter
}
})
</script>
</body>
</html>

注意事项
- 如果方法体, 只有简单的语句,比如 count++, 那么可以进行简写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<!--非组件化方式-普通方式-->
<button v-on:click="count++">点击次数= {{count}} 次【非组件化方式】</button><br/><br/>
</div>
<script>
new Vue({
el:"#app",
data:{
count:10,
count2: 10,
count3: 10
},
methods:{//methods属性, 可以定义相应的方法
click1(){
this.count++;
}
}
})
</script>
</body>
</html>
- 组件定义需要放置在 new Vue() 前,否则组件注册会失败
组件化小结
- 组件也是一个 Vue 实例,因此它的定义是也存在∶ data、methods、生命周期函数等
- data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据
- 组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板