1 模块与组件、模块化与组件化
1.1 模块
- 理解:向外提供特定功能的js程序,一般就是一个js文件
- 为什么使用模块:js文件很多很复杂
- 模块的作用:复用js代码,简化js的编写,提高js的运行效率
1.2 组件
- 理解:用来实现局部(特定)功能效果的代码合集(html/css/js/image…)
- 为什么使用组件:一个界面的功能很复杂
- 组件的作用:复用编码,简化项目编码,提高运行效率
1.3 模块化
如果应用中的js都是以模块来编写的,那这个应用就是一个模块化的应用。
1.4 组件化
当应用中的功能都是以组件的方式来编写的,那么这个应用就是一个组件化的应用。
2 组件的使用
2.1 组件的种类
分为非单文件组件和单文件组件
- 非单文件组件:一个文件中包含有多个组件
- 单文件组件:一个文件中只包含一个组件
2.2 组件使用的三个步骤
- 定义组件(创建组件)
- 注册组件
- 使用组件(写组件标签)
2.3 非单文件组件
2.3.1 定义非单文件组件
使用Vue.extend(options)
创建,其中options
和new Vue(options)
时传入的哪个options几乎一样,但也有区别:
- el不用写,因为最终所有的组件都要经过一个vm的管理,由vm中的el决定服务于哪个容器。
- data必须写成函数,避免组件被复用时数据存在引用关系。
**注意:**使用template可以配置组件结构。
2.3.2 注册非单文件组件
- 局部注册:靠new Vue时传入components选项
- 全局注册:考Vue.conmponent(“组件名”,组件)
2.3.3 使用组件
直接在html页面中的Vue服务的容器中编写组件标签
例如:<school></school>""
2.3.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>基本使用</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 编写组件标签 -->
<school></school>
<hr>
<student></student>
</div>
</body>
<script>
Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
// 创建school组件
const school = Vue.extend({
// el:'#app',
name:"school",
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
data(){
return {
name:"ycu",
address:"江西宜春",
}
},
})
// 创建学生组件
const student = Vue.extend({
// el:'#app',
name:"student",
template:`
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return {
name:"李四",
age:21,
}
},
})
Vue.component('student',student);
const vm = new Vue({
el:'#app',
// 局部注册组件
components:{
school,
},
mounted() {
},
});
</script>
</html>
2.4 创建组件需要注意的地方
2.4.1 组件名
- 一个单词组成:
- 第一种写法(首字母小写):
school
- 第二种写法(首字母大写):
School
- 第一种写法(首字母小写):
- 多个单词组成:
- 第一种写法(kebab-case命名):
my-school
- 第二种写法(CamelCase命名):
MySchool
(需要脚手架支持)
- 第一种写法(kebab-case命名):
- 注意
- 组件名尽可能回避HTML中已有的元素,例如h2,H2都不行
- 可以使用name配置项指定组件在开发者工具中呈现的名字
2.4.2 组件标签
- 第一种写法:
<school></school>
- 第二种写法:
<school>
或<school/>
- 注意:不使用脚手架时,
<school/>
会导致后续组件不能渲染
2.4.3 创建组件的简写方式
const school = Vue.extend(options)
可简写为const school = options
2.4.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>几个注意点</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>{{msg}}</h1>
<school></school>
<School></School>
<my-school></my-school>
<MySchool></MySchool>
<school/>
</div>
</body>
<script>
const school = Vue.extend({
name:"school",
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
data() {
return {
name:"ycu",
address:"江西宜春"
}
},
})
Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
const vm = new Vue({
el:'#app',
data(){
return {
msg:"欢迎学习Vue"
}
},
methods:{
},
mounted() {
},
components: {
school,
School:school,
"my-school":school,
MySchool:school,
},
});
</script>
</html>
2.5 组件的嵌套
测试代码
<!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>组件的嵌套</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<h2>{{msg}}</h2>
<!-- 编写组件标签 -->
<app></app>
</div>
</body>
<script>
Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
// 创建学生组件
const student = Vue.extend({
name:"student",
// el:'#app',
template:`
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return {
name:"李四",
age:21,
}
},
})
// 全局注册Student
// Vue.component("student",student)
// 创建school组件
const school = Vue.extend({
// el:'#app',
name:"school",
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<student></student>
</div>
`,
data(){
return {
name:"ycu",
address:"江西宜春",
}
},
// 局部注册组件
components:{
student,
}
})
// 创建hello组件
const hello = Vue.extend({
name:"hello",
template:`
<h2>{{msg}}</h2>
`,
data() {
return {
msg:"Vue什么牛马"
}
},
})
// 创建app组件
const app = Vue.extend({
name:"app",
template:`
<div>
<hello></hello>
<school></school>
</div>
`,
components:{
school,
hello
}
})
const vm = new Vue({
el:'#app',
data() {
return {
msg:"欢迎学习Vue"
}
},
// 局部注册组件
components:{
app
},
mounted() {
},
});
</script>
</html>
2.6 VueComponent
2.6.1 定义
VueComponent是一个构造函数,每一个的Vue组件的实例对象都是通过这个构造函数创建的。
2.6.2 验证VueComponent
<!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>VueComponent</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<school></school>
<hello></hello>
</div>
</body>
<script>
Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
// 创建school组件
const school = Vue.extend({
// el:'#app',
name:"school",
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
data(){
return {
name:"ycu",
address:"江西宜春",
}
},
methods:{
showName(){
console.log("showName",this);
}
}
})
// 创建hello组件
const hello = Vue.extend({
template:`
<h2>{{msg}}</h2>
`,
data() {
return {
msg:"你好"
}
},
})
console.log('@',school);
console.log('#',hello);
console.log(school===hello);
school.a = 99;
console.log('@',school.a);
console.log('#',hello.a);
const vm = new Vue({
el:'#app',
data(){
return {
}
},
methods:{
},
components: {
school,
hello
},
mounted() {
},
});
</script>
</html>
2.6.3 关于VueComponent
-
school组件本质是一个名为VueComponent的构造函数,且并不是程序员定义的,是Vue.extend生成的。
-
我们只需要些
<school></school>
,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行了new VueComponent(options)
。 -
**特别注意:**每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!
-
关于this的指向:
-
组件配置中
- data函数、methods中的函数、watch中的函数、computed中的函数,他们的this均是VueComponent实例对象。
-
new Vue(options)配置中
- data函数、methods中的函数、watch中的函数、computed中的函数,他们的this均是Vue实例对象。
-
-
VueComponent的实例对象,简称vc(亦可称之为:组件实例对象),Vue的实例对象,简称vm
2.7 分析Vue与VueComponent的内置关系
详见尚硅谷Vue视频
2.8 单文件组件
单文件组件需要依靠webpack或Vue脚手架才能运行。
2.8.1语法
html中的写法
// 创建学生组件
const student = Vue.extend({
name:"student",
template:`
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return {
name:"李四",
age:21,
}
},
})
student.vue
<template>
<div class="demo">
<h2>学生姓名:{{ name }}</h2>
<h2>学生年龄:{{ age }}</h2>
</div>
</template>
<script>
export default {
name: "Student",
data() {
return {
name: "李四",
age: 21,
}
},
}
</script>
<style>
.demo {
background-color: green;
}
</style>
2.8.2 单文件组件的嵌套
<template>
<div>
<School></School>
<Student></Student>
</div>
</template>
<script>
import School from './School.vue';
import Student from './Student.vue';
// 引入组件
export default {
name: "App",
components: { School, Student }
}
</script>
<style>
</style>