模块与组件、模块化与组件化
模块
-
什么是模块?向外提供特定功能的js程序,一般就是一个js文件
-
为什么要用模块?因为js文件很多很复杂
-
有什么作用?复用js,简化js的便携,提高js运行效率
组件
-
什么是组件?实现界面中局部(特定)功能代码和资源的集合(代码指html、css、js,资源指mp3、mp4、ttf、zip)
-
为什么要用组件?一个界面的功能很复杂
-
有什么作用?复用编码,简化项目编码,提高运行效率
模块化
当应用中的 js 都以模块来编写,那这个应用就是一个模块化的应用
组件化
当应用中的功能都是多组件的方式来编写的,那这个应用就是一个组件化的应用
非单文件组件
一个文件中包含有n个组件
基本使用
Vue中使用组件的三大步骤
- 定义组件(创建组件)
- 注册组件
- 使用组件(写组件标签)
一 . 如何定义一个组件?
使用Vue.extend(options)
创建,其中options
和new Vue(options)
时传入的那个options
几乎一样,但也有点区别,区别如下:
- el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
- data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。template 组件模板应该只包含一个根元素
二 . 如何注册组件?
局部注册:靠new Vue
的时候传入components
选项
全局注册:靠Vue.component(‘组件名’,组件)
注意:如果使用全局注册组件的时候记得单独创建vm
三 . 编写组件标签
<school></school>
全部代码:
<div id="root">
<!-- 第三步:编写组件标签 -->
<hello></hello>
<xuexiao></xuexiao>
<hr>
<xuesheng></xuesheng>
</div>
<div id="root2">
<hello></hello>
</div>
<script>
Vue.config.productionTip = false
// 第一步. 创建school组件
const school = Vue.extend({
template: `
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名字</button>
</div>
`,
// el: '#root', // 组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器
data() {
return {
schoolName: 'zcst',
address: '珠海'
}
},
methods: {
showName() {
alert(this.schoolName)
}
},
})
// 创建student组件
const student = Vue.extend({
template: `
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data() {
return {
studentName: '张三',
age: 18
}
}
})
// 创建hello组件
const hello = Vue.extend({
template: `
<div>
<h2>你好啊,{{name}}</h2>
</div>
`,
data() {
return {
name: 'Tom'
}
}
})
// 第二步:全局注册组件
Vue.component('hello', hello);
// 创建vm
new Vue({
el: '#root',
// 第二步. 注册组件(局部注册)
components: {
xuexiao: school,
xuesheng: student
}
})
// 创建vm
new Vue({
el: '#root2',
})
</script>
注意点
关于组件名
- 一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
- 多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool
(需要Vue脚手架支持) - 备注:
(1) 组件名尽可能回避HTML中已有的元素名称,例如:h2
、H2
都不行。
(2) 可以使用name配置项指定组件在开发者工具中呈现的名字。
关于组件标签
第一种写法:<school></school>
第二种写法:<school/>
一个简写方式
const school = Vue.extend(options)
可简写为:const school = options
备注:Vue会帮你判断是否有写extend方法,没有会帮你调一个
组件的嵌套
<app>
用来管理所有组件(规范写法)
app 一人之下(root)万人之上
如果要在组件里面再注册一个组件,这个子组件要在父组件的前面定义(创建),注意先后顺序
<div id="root">
<app></app>
</div>
<script>
Vue.config.productionTip = false
// 定义student组件
const student = Vue.extend({
template: `
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data() {
return {
name: '张三',
age: 18,
}
}
})
// 定义school组件
const school = Vue.extend({
template: `
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<student></student>
</div>
`,
data() {
return {
name: 'zcst',
address: '珠海',
}
},
// 注册组件(局部)
components: {
student
}
})
// 定义hello组件
const hello = Vue.extend({
template: `<h1>{{msg}}</h1>`,
data() {
return {
msg: '好困啊....'
}
}
})
// 定义app组件
const app = Vue.extend({
template: `
<div>
<hello></hello>
<school></school>
</div>
`,
components: {
hello,
school
}
})
// 创建vm
new Vue({
el: '#root',
// 注册组件(局部)
components: {
app
}
})
</script>
VueComponent
-
school
组件本质是一个名为VueComponent
的构造函数,且不是程序员定义的,是Vue.extend
生成的。
-
我们只需要写
<school></school>
或<school/>
,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)
。 -
特别注意:每次调用
Vue.extend
,返回的都是一个全新的VueComponent
!!!! -
关于this指向:
(1)组件配置中:
data
函数、methods
中的函数、watch
中的函数、computed
中的函数 它们的this均是【VueComponent实例对象】。
(2)new Vue(options)
配置中:
data
函数、methods
中的函数、watch
中的函数、computed
中的函数 它们的this均是【Vue实例对象(vm)】。 -
VueComponent
的实例对象,以后简称vc
(也可称之为:组件实例对象)。
Vue
的实例对象,以后简称vm
。
vm和vc
vc
有的功能,vm
都有,但是vm
有的一个功能,vc
没有vm
能够通过el
决定能为哪个容器服务vm
可以 管理着 多个vc
vc
是个小型的vm
- 另外,
vc
中data
必须写成函数形式data(){}
一个重要的内置关系
- 一个重要的内置关系:
VueComponent.prototype.__proto__ === Vue.prototype
(组件的原型的原型是Vue的原型) - 为什么要有这个关系:让组件实例对象(
vc
)可以访问到 Vue原型上的属性、方法。(让Vue的原型对象兜底,如果连Vue的原型对象都没有的话,就去找Object的原型对象)
单文件组件
一个文件中只包含1个组件
代码要有高亮,可以用这个插件,但是template里面要有个div,否则会报错
安装后快捷键是<v
然后回车,可以快速出来
步骤
创建组件
组件的命名为:
school
或 my-school
School
或 MySchool
最好选择这种
组件导出
引入到App.vue
引入到main.js里面
这里还没有创建容器,去index.html
里面创建容器
引入到index.html 创建容器
打开后发现无法显示,这因为浏览器不支持es6的模块化语法,此时就需要搭建脚手架环境