本篇图片截图来自尚硅谷:https://www.bilibili.com/video/BV1Zy4y1K7SH?p=53
什么是组件
组件是用来实现局部(特定)功能代码的集合(html、css、js、img、video…),尤其再界面功能很复杂的时候,有代码复用,简化项目编码,提高运行效率作用。
可以看一张很形象的图形解释:
为什么用组件
因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
为什么选择组件式编程:看两张图吧:
组建的基础
要想在项目中使用组件,要分三步实现:创建组件,注册组件,使用组件。
- 创建组件
- 使用
Vue.extend(options)
创建,其中options
和new Vew(options)
时传入的options
几乎一样,但是有区别:- 不写
el
:所有的组件都听从vm的管理,由vm的el决定服务于那个容器。 data
必须写成函数:避免组件复用时,数据存在引用关系。- 可以使用
template
配置组件结构。
- 不写
- 单词语组件名:‘school’
- 多词语组件名:“my-student” ,但是Vue展示的时候是
<MyStudent>
。 - 在脚手架里,多词语组件名:“MyStudent” 。
- 使用
- 注册组件:
- 局部注册:在
new Vue(options)
,给options
传入components
选项。 - 全局注册:
Vue.component("School",School);
- 在模块系统中局部注册:
- 现在 components 文件中创建 School.vue 单文件组件
- 再在App.vue 中引入:
import School from './Components/School' export default { //... components: { School , //... }, // ... }
- 局部注册:在
- 使用组件:
- 在非单文件组件中只能用:
<School></School>
。 - 在单文件组件中可以用:
<School />
- 在非单文件组件中只能用:
在非单文件中的组件代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello Vue</title>
<link rel="icon" href="../logo.svg">
</head>
<body>
<div id="root">
<h1>{{msg}}</h1>
<hr>
<!--使用组件-->
<School></School>
<hr>
学生组件:
<my-student></my-student>
<!-- 重复使用组件 -->
<my-student></my-student>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
Vue.config.productionTip=false;
// 创建Student组件
const Student=Vue.extend({
name:'Student',
template:`
<div>
<p>学生姓名:{{name}}</p>
<p>学生年龄:{{age}}</p>
<p>学生性别:{{sex}}</p>
</div>`,
data(){
return{
name:"张三",
age:18,
sex:"男"
}
}
})
// 创建School组件
const School = Vue.extend({
name:'School',
data(){
return{
name:"五道口技术学院",
add:"北京"
}
},
template:`
<div>
<p>学校名字:{{name}}</p>
<p>学校地址:{{add}}</p>
</div>
`
})
//注册组件(全局注册)
Vue.component("School",School);
var vm = new Vue({
el:"#root",
//注册组件(局部注册)
components:{
'my-student':Student,
//School:School, => School
},
data:{
msg:"hello Vue!"
}
})
</script>
</body>
</html>
效果:
组件嵌套
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello Vue</title>
<link rel="icon" href="../logo.svg">
</head>
<body>
<div id="root">
<h1>{{msg}}</h1>
<hr>
<!--使用组件-->
<School></School>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
Vue.config.productionTip=false;
// 创建Student组件
const Student=Vue.extend({
template:`
<div>
<p>学生姓名:{{name}}</p>
<p>学生年龄:{{age}}</p>
<p>学生性别:{{sex}}</p>
</div>`,
data(){
return{
name:"张三",
age:18,
sex:"男"
}
}
})
// 创建School组件
const School = Vue.extend({
data(){
return{
name:"五道口技术学院",
add:"北京"
}
},
components:{
'my-student':Student
},
template:`
<div>
<p>学校名字:{{name}}</p>
<p>学校地址:{{add}}</p>
<hr>
学生组件:
<!--嵌套组件-->
<my-student></my-student>
</div>
`
})
//注册组件(全局注册)
Vue.component("School",School);
var vm = new Vue({
el:"#root",
data:{
msg:"hello Vue!"
}
})
</script>
</body>
</html>
效果:
关于VueComponent
- School组件的本质是一个名为VueComponent的构造函数,是Vue.extend生成的。
- 我们只需要写
<School></School>
或者<School/>
Vue解析时会帮我们创建school的实例对象,帮我们执行new VueComponent(options)
。 - 依次调用 VueComponent,返回的都是一个全新的VueComponent实例。
扩展
- data的两种写法:
- new Vue() 时配置el属性
- 先创建Vue实例,然后再通过$mount("#root")指定el的值
- el的两种写法:
- 对象式
- 函数式
- 关于this指向:
Vue.extend()
配置中:data函数,methods / watch / component 中的函数、钩子函数 ,它们的this都是VueComponent实例对象。new Vue()
配置中:data函数,methods / watch / component 中的函数、钩子函数 ,它们的this都是Vue实例对象。
- 一个重要的原则:
- 由vue管理的函数,一定不要写箭头函数,因为箭头函数没有this,this就不再是Vue实例了。
- vue管理的函数内部的所有函数一律使用箭头函数,因为箭头函数没有this,this就指向Vue实例了。