Vue组件化编程
模块与组件、模块化与组件化
模块
前端世界里模块就是指的JS模块。
- 理解:向外提供特定功能的js程序,一般就是一个
js文件
。 - 为什么:js文件很多很复杂
- 作用:
复用js,简化js的编写,提高js运行效率
组件
- 组件定义:实现应用中**局部功能**代码和资源的集合。包括html、css、js
- 为什么:一个界面的功能很复杂
- 作用:
复用编码,简化项目编码,提高运行效率
模块化
应用中的JS代码太多,所以把JS拆写成各个JS文件(按照一定规则
)。
当应用中的JS代码都是用js模块
编写的,那么这个应用就是模块化应用
。
组件化
当应用中的功能都是用组件的方式
编写的,那么这个应用就是一个组件化应用
。
模块化、组件化对比
-
传统方式编写存在的问题:
-
关系混乱,不好维护的维护;JS模块化只关注解决JS的问题
-
代码复用率不高
-
-
组件方式编写应用:
-
每个组件包含:实现该部分内容的html结构、css样式、js交互
-
组件在复用时十分有优势:结构、样式和交互都可以复用。
-
非单文件组件
- 非单文件组件:一个文件中包含n个组件。
- 举例:一个html文件中包含多个vue组件
基本使用
使用组件的三个步骤:
-
定义组件
创建了组件,返回
VueComponent
构造函数 -
注册组件
在父组件中
import
导入组件,之后可以局部注册或者全局注册 -
使用组件
在
tempalte
中编写组件标签,返回组件实例
定义组件
-
使用
Vue.extend(options)
创建。其中
options
和new Vue(options)
时传入的那个options
几乎一样,但是也有区别:-
不写`el
最终所有的组件都要经过一个
vm
老大管理,由老大中的el
决定服务哪个容器。 -
data
必须写成函数防止数据污染:避免组件被复用时,数据存在引用关系,导致修改一个值会影响其他值,
-
举例说明
// 使用对象的方式,x1和x2会指向同一个对象 const data = { a: 1, b: 2 } const x1 = data const x2 = data console.log(x1) // {a:1,b:2} console.log(x2) // {a:1,b:2} x1.a = 99 console.log(x1) // {a:99,b:2} console.log(x2) // {a:99,b:2}
// 使用函数的方式,x1和x2指向不同的对象 function data(){ return { a: 1, b: 2 } } // 调用data函数时会返回新的对象,每调用一个都会产生全新的对象。 // x1和x2分别指向不同的内存空间,更新x1和x2的值不会收到对方影响。 // 因为存在引用,所以函数执行完毕该x1和x2指向的对象不会被内存回收。 const x1= data() const x2 = data() console.log(x1) // {a:1,b:2} console.log(x2) // {a:1,b:2} x1.a = 99 console.log(x1) // {a:99,b:2} console.log(x2) // {a:1,b:2}
所以Vue组件中要把data写成函数的形式,避免不同变量之间修改值互相影响。
-
-
注册组件
-
局部注册
- 方式:
new Vue
的时候传入components
选项
- 方式:
-
全局注册
-
方式:
Vue.component('组件名',组件)
-
组件是第一步定义的组件
-
组件名是给第三步写组件标签用的名字
一般这两者会写相同的名字。
-
-
编写组件标签
-
在html的body标签中写组件名称的标签。
-
举例:school是定义的组件,那么在body标签中写
<school></school>
组件命名注意点
组件中使用name属性可以设置在Vue开发者工具中显示的名称
下列代码中 在网页里面的Vue显示的名称为Atguigu
可以写单标签,自闭和。但是这种得在脚手架环境下
定义组件可以直接写对象花括号的形式,不写Vue.extend(options)
直接写成const a = options
的形式,但是Vue在底层会用Vue.extend
包裹
组件的嵌套
组件注册给谁,就在谁的components
属性里面写创建的组件。同时,就在谁的HTML结构中写组件名的标签。
注册给了谁,谁就是父亲。
VueComponent
第三点很重要,对后面的影响很大。
每次调用Vue.extend,返回的VueComponent都是在内存中不同空间的,
二者返回的不是一个
下面的图是错的,二者指向的都是自己调用Vue.extend返回的新的VueComponet函数,只是名字相同,但是组件指向的不同内存空间、
正确的写法
VC的实例对象受vm管理,挂在到vm的$children
上
如果vc实例还有子组件,那么继续挂在到vm的$children下的$children上
重要的内置联系
vm和vc并不相等
vc里面的data必须是函数,这样可以每次返回对象的独立拷贝
黄色的线强制的将让VueCompoenent构造函数的原型对象的__proto__
指向Vue的原型对象。
基础:想学会这个必须有原型基础
只要是对象就有__proto__
,指向构造函数的原型对象,
原型对象也是一个对象,会有__proto__
属性,继续向上指,指向Object的原型对象
实例的隐式原型属性永远指向自己缔造者的原型对象。
// // 创建一个Demo实例对象
const d = new Demo()
// 函数的prototype和实例的__proto__指向同一个同喜。
console.log(Demo.prototype) // 显示原型属性
console.log(d.__proto__) // 隐式原型属性
这么做的目的?
单文件组件
-
单文件组件:一个文件中只有1个组件。
- 后缀都是
.vue
的文件,里面只允许写一个组件 - 单文件组件更清晰,这种用的更多。
- 后缀都是
-
想让浏览器运行
.vue
后缀的文件,需要经过加工处理,方法有:-
webpack
-
脚手架(官方提供)
-
组件命名方法
- 一个单词:1.小写.vue 2.第一个单词大写.vue
- 多个单词:1.单词全部小写,用连字符连接 2.大驼峰
单文件组件基本结构
<template>
<!-- 组件结构 -->
<div></div>
</template>
<script>
// 组件交互相关代码
</script>
<style>
/* 组件样式代码 */
</style>
注意:
-
.vue
组件中只能写上面的三个标签,其他标签报错 -
<template>
标签中需要有唯一根节点,所以需要写一个<div>
标签