详解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 相关文章推荐
根据经纬度计算地球上两点之间的距离js实现代码
Mar 05 Javascript
使用js实现雪花飘落效果
Aug 26 Javascript
谈一谈JS消息机制和事件机制的理解
Apr 14 Javascript
原生js实现autocomplete插件
Apr 14 Javascript
javascript中对Date类型的常用操作小结
May 19 Javascript
浅谈JavaScript的全局变量与局部变量
Jun 10 Javascript
关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
Jun 13 Javascript
Vue.js 60分钟快速入门教程
Mar 28 Javascript
form表单序列化详解(推荐)
Aug 15 Javascript
React优化子组件render的使用
May 12 Javascript
vue data对象重新赋值无效(未更改)的解决方式
Jul 24 Javascript
原生JS实现音乐播放器的示例代码
Feb 25 Javascript
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
PHP在线生成二维码(google api)的实现代码详解
2013/06/04 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
2014/01/03 PHP
Yii2框架数据验证操作实例详解
2018/05/02 PHP
PHP开发实现快递查询功能详解
2019/04/08 PHP
JQuery 学习笔记01 JQuery初接触
2010/05/06 Javascript
JQuery最佳实践之精妙的自定义事件
2010/08/11 Javascript
通过jQuery源码学习javascript(二)
2012/12/27 Javascript
Jquery绑定事件(bind和live的区别介绍)
2013/08/23 Javascript
javascript解三阶幻方(九宫格)
2015/04/22 Javascript
jQuery子窗体取得父窗体元素的方法
2015/05/11 Javascript
JS组件中bootstrap multiselect两大组件较量
2016/01/26 Javascript
node.js 中国天气预报 简单实现
2016/06/06 Javascript
JavaScript每天必学之数组和对象部分
2016/09/17 Javascript
webpack常用配置项配置文件介绍
2016/11/07 Javascript
jQuery实现判断控件是否显示的方法
2017/01/11 Javascript
微信小程序 生命周期和页面的生命周期详细介绍
2017/01/19 Javascript
Vue.js实现一个漂亮、灵活、可复用的提示组件示例
2017/03/17 Javascript
antd组件Upload实现自己上传的实现示例
2018/12/18 Javascript
《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析
2020/04/08 Javascript
vue 添加和编辑用同一个表单,el-form表单提交后清空表单数据操作
2020/08/03 Javascript
[36:19]2018DOTA2亚洲邀请赛 小组赛 A组加赛 Newbee vs LGD
2018/04/03 DOTA
[36:33]2018DOTA2亚洲邀请赛 4.3 突围赛 EG vs Newbee 第二场
2018/04/04 DOTA
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python使用urllib2模块获取gravatar头像实例
2013/12/18 Python
介绍Python的@property装饰器的用法
2015/04/28 Python
python实现文本文件合并
2015/12/29 Python
Python实现简易Web爬虫详解
2018/01/03 Python
完美解决Python 2.7不能正常使用pip install的问题
2018/06/12 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
python创建ArcGIS shape文件的实现
2019/12/06 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
Python flask框架如何显示图像到web页面
2020/06/03 Python
Pycharm配置lua编译环境过程图解
2020/11/28 Python
html5的canvas方法使用指南
2014/12/15 HTML / CSS
2014年工作总结及2015工作计划
2014/12/12 职场文书
《当代神农氏》教学反思
2016/02/23 职场文书