详解Vue 中 extend 、component 、mixins 、extends 的区别


Posted in Javascript onDecember 20, 2017

new Vue()、component

首先我们来约定一个选项对象 baseOptions,后面的代码会用到.

let options = {
 template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
 data: function () {
  return {
   firstName: 'Walter',
   lastName: 'White',
   alias: 'Heisenberg'
  }
 },
 created(){
  console.log('onCreated-1');
 }
};

new Vue() source:vue/src/core/instance/index.js

实例化一个组件.

new Vue(baseOptions);
// -> onCreated-1
component source:vue/src/core/global-api/assets.js

Vue.component 是用来注册或获取全局组件的方法,其作用是将通过 Vue.extend 生成的扩展实例构造器注册(命名)为一个组件.全局注册的组件可以在所有晚于该组件注册语句构造的Vue实例中使用.

Vue.component('global-component', Vue.extend(baseOptions));
//传入一个选项对象(自动调用 Vue.extend),等价于上行代码.
Vue.component('global-component', baseOptions);
// 获取注册的组件(始终返回构造器)
var MyComponent = Vue.component('my-component')

当我们需要在其他页面‘扩展'或者叫‘混合'baseOptions时,Vue中提供了多种的实现方式:extend,mixins,extends.

extend source:vue/src/core/global-api/extend.js

可以扩展 Vue 构造器,从而用预定义选项创建可复用的组件构造器。

let BaseComponent = Vue.extend(baseOptions);
//基于基础组件BaseComponent,再扩展新逻辑.
new BaseComponent({
 created(){
  //do something
  console.log('onCreated-2');
 }
 //其他自定义逻辑
});
// -> onCreated-1
// -> onCreated-2

mixins

mixins 选项接受一个混合对象的数组。这些混合实例对象可以像正常的实例对象一样包含选项,他们将在 Vue.extend() 里最终选择使用相同的选项合并逻辑合并。

new Vue({
 mixins: [baseOptions],
 created(){
  //do something
  console.log('onCreated-2');
 }
 //其他自定义逻辑
});
// -> onCreated-1
// -> onCreated-2

extends

这和 mixins 类似,区别在于,组件自身的选项会比要扩展的源组件具有更高的优先级.

官方文档是这么写的,除了优先级,可能就剩下接受参数的类型吧,mixins接受的是数组.

new Vue({
 extends: baseOptions,
 created(){
  //do something
  console.log('onCreated-2');
 }
 //其他自定义逻辑
});
// -> onCreated-1
// -> onCreated-2

从结果上看,三种方式都能实现需求,但是形式却有不同.

  • Vue.extend
  • Vue.extend只是创建一个构造器,他是为了创建可复用的组件.
  • mixins,extends
  • 而mixins和extends是为了拓展组件.

从源码来看通过extend,extends和mixins三种方式接收的options,最终都是通过mergeOptions进行合并的.差异只是官方文档中提到的优先级不同extend > extends > mixins. 所以,如果是简单的扩展组件功能,三个方式都可以达到目的.

详解Vue 中 extend 、component 、mixins 、extends 的区别

而这三种方式使用场景上细化的区分,目前我也蒙圈中...

//几种方式的不同示例:

https://jsfiddle.net/willnewi...

选项对象合并策略 Vue.config.optionMergeStrategies

上面提到的选项对象,是在mergeOptions中按照一定策略进行合并的.

打印Vue.config.optionMergeStrategies,你会看默认的optionMergeStrategies如下:

详解Vue 中 extend 、component 、mixins 、extends 的区别

  • mergeHook
  • 子组件和父组件的生命周期事件会合并在一个数组里。父组件在前,子组件在后。
  • watch
  • 子组件和父组件的watchers会合并在一个数组里。父组件在前,子组件在后。
  • mergeAssets(filters,components,directives)
  • 首先会在子组件里查找,如果没有,才会沿着原型链向上,找父组件中对应的属性。
  • data 合并规则
  • 无重复的属性保留
  • 同名覆盖
  • data中的对象也是相同规则,无重复的属性保留,同名覆盖
  • props、methods、computed: 无重复保留,同名子组件覆盖父组件

mergeAssets

mergeAssets合并方法里,用到了原型委托.他会先把父组件的属性放在创建的新对象的原型链上.然后扩展新对象

对象里查找属性的规则 :举个例子,当查找一个属性时,如 obj[a] ,如果 obj 没有 a 这个属性,那么将会在 obj 对象的原型里找,如果还没有,在原型的原型上找,直到原型链的尽头,如果还没有找到,返回 undefined。

function extend (to, _from) {
 for (var key in _from) {
 to[key] = _from[key];
 }
 return to
}
function mergeAssets (parentVal, childVal) {
 var res = Object.create(parentVal || null);
 return childVal
 ? extend(res, childVal)
 : res
}

总结

  • Vue.component 注册全局组件,为了方便
  • Vue.extend 创建组件的构造函数,为了复用
  • mixins、extends 为了扩展

如果按照优先级去理解,当你需要继承一个组件时,可以使用Vue.extend().当你需要扩展组件功能的时候,可以使用extends,mixins.但目前为止还没有碰到完美诠释他们的场景,抱歉,能力有限?

Javascript 相关文章推荐
html中使用javascript调用本地程序(exe、doc等)实现代码
Apr 26 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
Sep 02 Javascript
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
Dec 12 Javascript
不提示直接关闭网页窗口的JS示例代码
Dec 17 Javascript
学习JavaScript设计模式之装饰者模式
Jan 19 Javascript
Node.js插件安装图文教程
May 06 Javascript
详解jQuery中的DOM操作
Dec 23 Javascript
利用ES6的Promise.all实现至少请求多长时间的实例
Aug 28 Javascript
C#实现将一个字符转换为整数
Dec 12 Javascript
JS实现秒杀倒计时特效
Jan 02 Javascript
token 机制和实现方式
Dec 15 Javascript
vue-router中hash模式与history模式的区别
Jun 23 Vue.js
vue.js vue-router如何实现无效路由(404)的友好提示
Dec 20 #Javascript
详解vue mixins和extends的巧妙用法
Dec 20 #Javascript
canvas轨迹回放功能实现
Dec 20 #Javascript
jQuery实现动态控制页面元素的方法分析
Dec 20 #jQuery
js实现以最简单的方式将数组元素添加到对象中的方法
Dec 20 #Javascript
浅谈gulp创建完整的项目流程
Dec 20 #Javascript
vue使用axios实现文件上传进度的实时更新详解
Dec 20 #Javascript
You might like
如何分别全角和半角以避免乱码
2006/10/09 PHP
php计算2个日期的差值函数分享
2015/02/02 PHP
Laravel接收前端ajax传来的数据的实例代码
2017/07/20 PHP
JS Excel读取和写入操作(模板操作)实现代码
2010/04/11 Javascript
使用jQuery UI的tooltip函数修饰title属性的气泡悬浮框
2013/06/24 Javascript
JS.GetAllChild(element,deep,condition)使用介绍
2013/09/21 Javascript
Bootstrap基本插件学习笔记之轮播幻灯片(23)
2016/12/08 Javascript
基于ES6 Array.of的用法(实例讲解)
2017/09/05 Javascript
详解基于electron制作一个node压缩图片的桌面应用
2019/01/29 Javascript
js类的继承定义与用法分析
2019/06/21 Javascript
typescript nodejs 依赖注入实现方法代码详解
2019/07/21 NodeJs
Js生成随机数/随机字符串的方法小结【5种方法】
2020/05/27 Javascript
[58:32]EG vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[53:50]CHAOS vs Mineski 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
解决tensorflow测试模型时NotFoundError错误的问题
2018/07/26 Python
Python 经典面试题 21 道【不可错过】
2018/09/21 Python
CSS3教程(6):创建网站多列
2009/04/02 HTML / CSS
Mio Skincare美国官网:身体紧致及孕期身体护理
2017/03/05 全球购物
Laura Mercier官网:彩妆大师罗拉玛斯亚的化妆品牌
2018/01/04 全球购物
介绍一下SQL注入攻击的种类和防范手段
2012/02/18 面试题
维德科技C#面试题笔试题
2015/12/09 面试题
办公室主任职责范文
2013/11/08 职场文书
上班离岗检讨书
2014/01/27 职场文书
大四毕业生自荐书
2014/07/05 职场文书
员工安全生产责任书
2014/07/22 职场文书
2014年小学辅导员工作总结
2014/12/23 职场文书
先进典型事迹材料
2014/12/29 职场文书
2015年世界无烟日活动方案
2015/05/04 职场文书
《祁黄羊》教学反思
2016/02/20 职场文书
小学2016年“我们的节日·重阳节”活动总结
2016/04/01 职场文书
jQuery实现影院选座订座效果
2021/04/13 jQuery
关于Javascript闭包与应用的详解
2021/04/22 Javascript
浅谈python中的多态
2021/06/15 Python
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js
python多次执行绘制条形图
2022/04/20 Python
Python循环之while无限迭代
2022/04/30 Python