文章目录
Vue–组件化编程
储备知识
模块
- 理解: 向外提供特定功能的 js 程序, 一般就是一个 js 文件
- 为什么: js 文件很多很复杂
- 作用: 复用 js, 简化 js 的编写, 提高 js 运行效率
【前端的世界里,模块指的就是JS模块,css与HTML不需要模块】
组件
-
理解: 用来实现局部(特定)功能效果的代码集合(html/css/js/image……)
-
为什么: 一个界面的功能很复杂
-
作用: 复用编码, 简化项目编码, 提高运行效率
模块化
当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用。
组件化
当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用。
一个重要的原则
由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。
传统方式编写应用
【复制代码使用 ≠ 代码复用,除非如上例子,单独将顶部与底部html代码抽离成外部文件(使用 str 存储相关字符串),然后在两个HTML文件中引用即为复用】
组件方式编写应用
组件的定义:实现应用中局部功能代码和资源的集合
keywords:
局部
代码
资源
集合
组件的两种编写方式
非单文件组件 *
定义:一个文件中包含n个组件
弊端:
- 模板编写没有提示
- 没有构建过程, 无法将 ES6 转换成 ES5
- 不支持组件的 CSS
- 真正开发中几乎不用
如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
区别如下:
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。
- 创建hello组件
//创建hello组件
const hello = Vue.extend({
template:`
<div>
<h2>你好啊!{{name}}</h2>
</div>
`,
data(){
return {
name:'Tom'
}
}
})
如何注册组件?
1.局部注册:靠new Vue的时候传入components选项
2.全局注册:靠Vue.component(‘组件名’,组件)
- 创建vm 并注册组件
//创建vm
new Vue({
el:'#root',
data:{
msg:'你好啊!'
},
//第二步:注册组件(局部注册)
components:{
hello,
}
})
//全局注册组件
Vue.component('hello',hello)
同理创建并注册其他文件,非单文件组件(一个文件包含n个组件)
【全局注册的使用时机,多个组件中都要使用当前组件】
Vue.component(Pagination.name, Pagination),第一个参数传入的是组件使用时候的名字,第二个参数是组件的来源。组件名尽量大写开头,即Vue.component(‘组件名’,组件)
编写组件标签
一个简写方式:
const school = Vue.extend(options)
可简写为:const school = options
源码:
function extend (to, _from) {
// debugger
for (var key in _from) {
to[key] = _from[key];
}
return to
}
【在VM中注册组件时,底层会判断传入的组件是对象还是函数,若是对象则会自动执行 Vue.extend() 】
关于VueComponent
1.组件(hello)本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
console.log(school),输出如下
2.我们只需要写或,Vue解析时会帮我们创建hello组件的实例对象,即Vue帮我们执行的:new VueComponent(options)。
验证如下: 控制台输出:“VueComponent被调用了!!”。 既验证了构造函数,也验证了实例对象(可debugger)
源码:
var Sub = function VueComponent (options) {
// console.log("VueComponent被调用了!!")
this._init(options);
};
3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!
验证方式一: 使用 ===
验证方式二: shool.a = 88 输出 hello.a --> undefined
验证方式三: 源码
Vue.extend = function (extendOptions) {
/***********/
var Sub = function VueComponent (options) {
// console.log("VueComponent被调用了!!")
this._init(options);
};
/***********/
return Sub
}
4.关于this指向:
(1).组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
(2).new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
5.VueComponent的实例对象,以后简称vc[非官方](也可称之为:组件实例对象)。
Vue的实例对象,以后简称vm。
VM管理所有的组件,包括嵌套组件
【VM ≠ VC 】
- VM的配置项有el,VC没有
- VM指定为哪个容器服务,VC跟着VM服务
- VM的data可以是函数式也可以是对象式,但是VC的data只能是函数式
- 联系:底层在创建VC和VM的时候相当一部分代码时复用的
官网直达:Vue2–>教程—>组件基础 组件是可复用的 Vue 实例,所以它们与 new Vue
接收相同的选项,例如 data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像 el
这样根实例特有的选项。
一个组件的 data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
一个重要的内置关系
1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
console.log(school.prototype.__proto__ === Vue.prototype); //true
【查看一个函数身上的属性跟方法,console.dir(Vue)】
验证:Vue.prototype.x = 99
在shool的配置项中拿到this.x
单文件组件
定义:一个文件中只包含1个组件
【一个 .vue 就是一个组件】
实际开发中常使用单文件组件的方式开发
一个.vue 文件的组成
- 模板页面
2.JS 模块对象
- 样式
基本使用
- 引入组件
- 映射成标签
- 使用组件标签
Vue中使用组件的步骤
一、定义组件(创建组件)
二、注册组件
三、使用组件(写组件标签)
组件中的注意事项
-
组件中的data必须使用函数式,否则会报错。
vue.js:634 [Vue warn]: The “data” option should be a function that returns a per-instance value in component definitions.
【组件存在的意义是为了复用,在组件A中引用了组件K,在组件B中也引用了组件K,但是不希望在A中的组件K数据变化时影响B中的组件K的数据】
对象式:
let data = {
a: 1,
b: 2,
}
const x1 = data
const x2 = data
【data:模拟组件K中的data,x1与x2组件A与组件B中引用的组件K身上的data】
函数式:
function data(){
return {
a: 1,
b: 2
}
}
const x1 = data()
const x2 = data()
【注意:不要写成const x1 = data ; const x2 = data】
- 组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
- 组件命名:MyShool(脚手架不报错) 或 ‘my-shool ’,可以使用name配置项指定组件在开发者工具中呈现的名字。
函数式:
function data(){
return {
a: 1,
b: 2
}
}
const x1 = data()
const x2 = data()
【注意:不要写成const x1 = data ; const x2 = data】
- 组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
- 组件命名:MyShool(脚手架不报错) 或 ‘my-shool ’,可以使用name配置项指定组件在开发者工具中呈现的名字。