详解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 相关文章推荐
jquery 图片Silhouette Fadeins渐显效果
Feb 07 Javascript
jQuery boxy弹出层插件中文演示及使用讲解
Feb 24 Javascript
js汉字转拼音实现代码
Feb 06 Javascript
Javascript中浮点数相乘的一个解决方法
Jun 03 Javascript
jQuery中常用的遍历函数用法实例总结
Sep 01 Javascript
浅谈在js传递参数中含加号(+)的处理方式
Oct 11 Javascript
详解基于Node.js的微信JS-SDK后端接口实现代码
Jul 15 Javascript
bootstrap模态框关闭后清除模态框的数据方法
Aug 10 Javascript
小程序文字跑马灯效果
Dec 28 Javascript
vue store之状态管理模式的详细介绍
Jun 13 Javascript
js实现指定时间倒计时效果
Aug 26 Javascript
超详细小程序定位地图模块全系列开发教学
Nov 24 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实现的下载css文件中的图片的代码
2010/02/08 PHP
Look And Say 序列php实现代码
2011/05/22 PHP
PHP网站建设的流程与步骤分享
2015/09/25 PHP
php断点续传之文件分割合并详解
2016/12/13 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
2018/12/21 PHP
JS控制显示隐藏兼容问题(IE6、IE7、IE8)
2010/04/01 Javascript
javascript当中的代码嗅探扩展原生对象和原型(prototype)
2013/01/11 Javascript
分析Node.js connect ECONNREFUSED错误
2013/04/09 Javascript
js原生appendChild的bug解决心得分享
2013/07/01 Javascript
js正则表达式的使用详解
2013/07/09 Javascript
js中的caller和callee属性介绍和例子
2014/06/07 Javascript
45个JavaScript编程注意事项、技巧大全
2015/02/11 Javascript
在JavaScript中操作时间之getUTCDate()方法的使用
2015/06/10 Javascript
javascript 判断页面访问方式电脑或者移动端
2016/09/19 Javascript
js格式化时间的简单实例
2016/11/27 Javascript
JS正则表达式修饰符中multiline(/m)用法分析
2016/12/27 Javascript
详解微信小程序开发之城市选择器 城市切换
2017/01/17 Javascript
Vue2.0中三种常用传值方式(父传子、子传父、非父子组件传值)
2018/08/16 Javascript
JS实现点击拉拽轮播图pc端移动端适配
2018/09/05 Javascript
[06:04]DOTA2英雄梦之声Vol19卓尔游侠
2014/06/20 DOTA
python插入排序算法的实现代码
2013/11/21 Python
Python中几种操作字符串的方法的介绍
2015/04/09 Python
python获取从命令行输入数字的方法
2015/04/29 Python
python下os模块强大的重命名方法renames详解
2017/03/07 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
对Django项目中的ORM映射与模糊查询的使用详解
2019/07/18 Python
详解Python修复遥感影像条带的两种方式
2020/02/23 Python
如何将PySpark导入Python的放实现(2种)
2020/04/26 Python
打印tensorflow恢复模型中所有变量与操作节点方式
2020/05/26 Python
利用Python批量识别电子账单数据的方法
2021/02/08 Python
会计试用期自我评价怎么写
2014/09/18 职场文书
2015年党员公开承诺书范文
2015/01/22 职场文书
降价通知函
2015/04/23 职场文书
2016元旦主持人经典开场白台词
2015/12/03 职场文书
如何使用php生成zip压缩包
2021/04/21 PHP
MongoDB数据库之添删改查
2022/04/26 MongoDB