组件化开发
直观地将一个复杂的页面分割成若干个独立的组件,每个组件都包含自己的逻辑和样式(html、css、js),再将这些组件自由组合起来形成完整的界面。
个人感觉组件化很符合编程的思想,能重复多次使用的就封装起来,提高代码的可维护性
组件化开发的好处
- 提高开发效率
- 方便重复使用
- 便于协同开发
- 更容易被管理和维护
组件分类
按功能分
- 页面级组件:一个页面就是一个组件
- 基础组件:将可复用的部分抽离出来,形成基础组件
按用法分
- 全局组件:可以声明一次在任何地方使用,一般写插件或者是使用很频繁时候常用
- 局部组件:必须告诉这个组件属于谁
Vue中的组件
vue中的组件是自定义标签(除原生html的元素如 div p span a header section。。。),可以扩展原生的html元素,封装可重用的代码。
组件的组成
Vue组件的使用:
- 组件名不要带有大写,多个单词用 “-” 连接’
- 只要组件名和定义名字相同是可以的(首字母可以大写)
- html采用短横线隔开命名法,js中转驼峰也是可以的
- 组件是相互独立的,不能直接跨作用域,实例也是一个组件,组件中拥有声明周期函数
- 如果组件共用了数据,会导致同时更新(独立性)
- 子组件不能直接使用父组件的数据(组件之间的数据交互)
- 组件理论上可以无限嵌套
1) 全局组件
Vue.component('mydiv', { // 一个对象可以看成一个组件
template: '<div>{{ msg }}</div>',
data(){ // 组件中的数据必须是函数类型,返回一个实例作为组件的数据
return {
msg: '是日前端'
}
}
})
2) 局部组件
- 创建组件
let mydiv = { template: '<div>{{ msg }}</div>' };
- 注册组件
components: {
mydiv
}
- 引用组件
在页面中使用
<mydiv></mydiv>
所以data必须是函数形式,保证不能返回同一个对象,不能是单例的,
首先在组件中data不能使用对象形式,必须用函数形式,(vue实例除外,是对象形式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<Counter></Counter>
<Counter></Counter>
<Counter></Counter>
</div>
<template id="con">
<div>
<button @click="add">你点击了{{ count }} 次</button>
</div>
</template>
<script src="vue.js"></script>
<script>
let Counter = {
template: '#con',
data: {
count: ''
},
methods: {
add(){
this.count ++
}
}
}
console.log(Counter)
let vm = new Vue({
el: '#app',
data: {},
components: {
Counter
}
})
</script>
</body>
</html>
修改后例子如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<Counter></Counter>
<Counter></Counter>
<Counter></Counter>
</div>
<template id="con">
<div>
<button @click="add">你点击了{{ count }} 次</button>
</div>
</template>
<script src="vue.js"></script>
<script>
let obj = {
count: 0
}
let Counter = {
template: '#con',
data(){
return obj
},
methods: {
add(){
this.count ++
}
}
}
console.log(Counter)
let vm = new Vue({
el: '#app',
components: {
Counter
}
})
</script>
</body>
</html>
初始状态:
任意点击一个按钮:
这时候组件之间就在互相影响了,共用了同一个data
data不返回同一个对象时,则组件之间互相独立
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<Counter></Counter>
<Counter></Counter>
<Counter></Counter>
</div>
<template id="con">
<div>
<button @click="add">你点击了{{ count }} 次</button>
</div>
</template>
<script src="vue.js"></script>
<script>
let Counter = {
template: '#con',
data(){
return {
count: 0
}
},
methods: {
add(){
this.count ++
}
}
}
console.log(Counter)
let vm = new Vue({
el: '#app',
components: {
Counter
}
})
</script>
</body>
</html>
原理:
因为组件的data返回的都是同一个对象,相当于指向的地址相同,指向的都是vm实例上的data对象,改变的时候,都是改变的同一个对象。
再说点内存的知识:
内存控键分为栈内存和堆内存,栈内存是线性排列的空间,大小是固定的,可以直接根据值来访问;
堆内存是保存的内存地址(引用),通过地址去访问。
Js中没有栈堆概念,引入它为了方便理解和更好的学习:
基本数据类型都保存在栈里:number string boolean null undefined
对象、数据、函数等是存储在堆上的,创建一个新对象就会开辟一块新空间
当返回不同对象的时候,每个组件都会生成一个新的实例对象
总结
因为我们一般不想让组件之间共享数据,互相影响,需要各组件之间独立,所以都让组件返回一个新对象
杂谈: 这个问题解决了我前两天想在同一个页面中多次复用组件的问题,组件之间是互相独立的,完全可以多次复用