1. 模块与组件、模块化与组件化
- 模块
向外提供特定功能的js程序,一般就是一个js文件;
js文件很多很杂 ⟶ \longrightarrow ⟶ 复用js,简化js的编写,提高js的运行效率。 - 组件
实现应用中局部功能代码和资源的集合。
一个界面的功能很复杂 ⟶ \longrightarrow ⟶ 复用编码,简化项目编码,提高运行效率。 - 模块化
当应用中的js都是以模块来编写的,那这个应用就是一个模块化应用。 - 组件化
当应用中的功能都是以多组件的方式编写的,那这个应用就是一个组件化的应用。 - 非单文件组件
一个文件中包含n个组件。 - 单文件组件
一个文件中只包含一个组件。
2. 非单文件组件
定义组件(创建组件) ⟶ \longrightarrow ⟶ 注册组件 ⟶ \longrightarrow ⟶ 使用组件(写组件标签)
2.1. 定义组件
const 组件名 = Vue.extend(options)
,可以简写为const 组件名 = options
options为配置对象,与实例化Vue时的options几乎一样,但要注意:
不能写el
: 最终所有的组件都要经过一个vm管理,由vm中的el决定服务哪个容器;
data
必须写成函数: 避免组件被复用时,数据存在引用关系。
备注:使用template
可以配置组件结构。
2.2. 注册组件
局部注册:new Vue()
时传入components
选项;
全局注册:new Vue(‘组件名’, 组件)
- 组件名
由一个单词组成:首字母大写或小写均可,如:School
、school
由多个单词组成:都用小写,单词之间用-
连接,并用''
引起来,如:'my-school'
;每个单词首字母都大写,如:MySchool
,需要Vue脚手架支持。
组件名应尽可能回避HTML中已有的元素名称;
可以用name
配置项指定组件在开发者工具中呈现的名字。
2.3. 使用组件
- 编写组件标签
开始 - 结束标签:<组件名></组件名>
,如<school></school>
;
自闭合标签:<组件名/>
,如<school/>
,但不使用Vue脚手架时会导致后续组件不能渲染。
2.4. 举例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue2</title>
<link rel="shortcut icon" href="../imgs/kirlant.ico">
<script type="text/javascript" src="../vue/vue.js"></script>
<style>
#root{
width: 400px;
border: 2px solid #aaa;
padding: 10px 0;
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-content: center;
}
.title{
width: 80%;
font-weight: bold;
text-align: center;
border-bottom: solid 1.5px #aaa;
padding-bottom: 5px;
}
.gap{
padding: 5px 20px;
border-top: solid 1px #aaa;
text-align: left;
}
</style>
</head>
<body>
<div id="root">
<div class="title">Welcome to yyt's Test</div>
<!-- 3. 编写组件标签 -->
<school></school>
<student></student>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false;
// 1. 创建组件
const school = Vue.extend({
template:`
<div class="gap" >
<p>学校名称:{{name}}</p>
<p>学校地址:{{address}}</p>
<button @click="showName">alert school name</button>
</div>
`,
data(){
return {
name:'SWJTU',
address:'Sichuan Chengdu'
}
},
methods: {
showName(){
alert(this.name);
}
}
});
const student = Vue.extend({
template:`
<div class="gap">
<p>学生姓名:{{name}}</p>
<p>学生年龄:{{age}}</p>
</div>
`,
data(){
return {
name:'kirlant',
age:16
}
}
});
// 实例化 Vue
new Vue({
el:'#root',
// 2. 注册组件(局部)
components:{
school:school,
student:student
}
});
</script>
</html>
2.5. 组件的嵌套
所有的组件都由一个名为App
的组件管理。


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue2</title>
<link rel="shortcut icon" href="../imgs/kirlant.ico">
<script type="text/javascript" src="../vue/vue.js"></script>
<style>
.root{
width: 400px;
border: 2px solid #aaa;
padding: 10px 0;
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-content: center;
}
.title{
width: 80%;
font-weight: bold;
text-align: center;
border-bottom: solid 1.5px #aaa;
padding-bottom: 5px;
}
.gap{
padding: 5px 0;
border-top: solid 1px #aaa;
text-align: left;
}
</style>
</head>
<body>
<div id="root">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false;
// 1. 创建 welcome 组件
const Welcome = Vue.extend({
template:`
<div class="title">
Welcome to {{name}}'s Test
</div>
`,
data(){
return {name:'yyt'};
}
});
// 1. 创建 student 组件
const Student = Vue.extend({
template:`
<div class="gap">
<p>学生姓名:{{name}}</p>
<p>学生年龄:{{age}}</p>
</div>
`,
data(){
return {
name:'kirlant',
age:16
}
}
});
// 1. 创建 school 组件
const School = Vue.extend({
template:`
<div class="gap" >
<p>学校名称:{{name}}</p>
<p>学校地址:{{address}}</p>
<Student></Student>
</div>
`,
data(){
return {
name:'SWJTU',
address:'Sichuan Chengdu'
}
},
components:{
Student
}
});
// 1. 创建 App 组件
const App = Vue.extend({
template:`
<!-- 3. 编写组件标签 -->
<div class='root'>
<Welcome></Welcome>
<School></School>
</div>
`,
components:{
Welcome,
School
}
});
// 实例化 Vue
new Vue({
el:'#root',
// 3. 编写组件标签
template:`<App></App>`,
// 2. 注册组件(局部)
components:{ App }
});
</script>
</html>
2.6. VueComponent
- 组件本质上是一个名为
VueComponent
的构造函数,且不是程序员定义的,而是Vue.extend
生成的; - 我们只需要编写组件标签,Vue解析模板时会帮我们创建组件的实例对象,即Vue执行了
new VueComponent(options)
; - 每次调用
Vue.extend
,返回的都是一个全新的VueComponent
; this
- data函数、methods中的函数、watch中的函数、computed中的函数
new Vue()
配置中:Vue
实例对象(vm
);
组件配置中:VueComponent
实例对象;
2.7. 内置关系VueComponent.prototype.__proto__ === Vue.prototype
对VueComponent.prototype
的隐式原型对象进行了重定位,让它指向Vue
的显式原型对象,让组件实例对象可以访问Vue
原型上的的属性、方法。
3. 单文件组件 组件名.vue
举例:school.vue
在其他组件中引用时,用import School from './School.vue';
导入。
<!-- 组件的结构 -->
<template>
<div class="gap" >
<p>学校名称:{{name}}</p>
<p>学校地址:{{address}}</p>
<button @click="showName">alert school name</button>
</div>
</template>
<!-- 组件交互 - 数据、方法 -->
<script>
export default {
name:'School',
data(){
return {
name:'SWJTU',
address:'Sichuan Chengdu'
}
},
methods: {
showName(){
alert(this.name);
}
}
};
</script>
<!-- 组件的样式 -->
<style>
.gap{
padding: 5px 0;
border-top: solid 1px #aaa;
text-align: left;
}
</style>