详解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 相关文章推荐
JavaScript 滚轮事件使用说明
Mar 07 Javascript
js设置组合快捷键/tabindex功能的方法
Nov 21 Javascript
zeroclipboard 单个复制按钮和多个复制按钮的实现方法
Jun 14 Javascript
PHP PDO操作总结
Nov 17 Javascript
jquery 设置style:display的方法
Jan 29 Javascript
基于jquery实现轮播特效
Apr 22 Javascript
JS中this上下文对象使用方式
Oct 09 Javascript
基于jQuery实现的查看全文功能【实用】
Dec 11 Javascript
JS实现超简单的汉字转拼音功能示例
Dec 22 Javascript
jquery.picsign图片标注组件实例详解
Feb 02 jQuery
小程序点击图片实现自动播放视频
May 29 Javascript
小程序开发踩坑:页面窗口定位(相对于浏览器定位)(推荐)
Apr 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
re0第二季蕾姆被制作组打入冷宫!艾米莉亚女主扶正,原因唏嘘
2020/04/02 日漫
网络资源
2006/10/09 PHP
PHP代码审核的详细介绍
2013/06/13 PHP
PHP OPP机制和模式简介(抽象类、接口和契约式编程)
2014/06/09 PHP
mac环境中使用brew安装php5.5.15
2014/08/18 PHP
详解WordPress中简码格式标签编写的基本方法
2015/12/22 PHP
Javascript 中文字符串处理额外注意事项
2009/11/15 Javascript
JQuery分别取得每行最后一列和最后一行的示例代码
2013/08/18 Javascript
JavaScript插件化开发教程(五)
2015/02/01 Javascript
值得分享的Bootstrap Ace模板实现菜单和Tab页效果
2015/12/30 Javascript
基于Javascript实现弹出页面效果
2016/01/01 Javascript
Bootstrap基本插件学习笔记之Tooltip提示工具(18)
2016/12/08 Javascript
JS实现微信弹出搜索框 多条件查询功能
2016/12/13 Javascript
JS使用面向对象技术实现的tab选项卡效果示例
2017/02/28 Javascript
详解vue-cli项目中用json-sever搭建mock服务器
2017/11/02 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
2017/12/25 Javascript
微信小程序云开发如何使用云函数生成二维码
2019/05/18 Javascript
django将数组传递给前台模板的方法
2019/08/06 Python
Python使用Beautiful Soup爬取豆瓣音乐排行榜过程解析
2019/08/15 Python
python获取引用对象的个数方式
2019/12/20 Python
python之MSE、MAE、RMSE的使用
2020/02/24 Python
使用 Python 遍历目录树的方法
2020/02/29 Python
Keras之fit_generator与train_on_batch用法
2020/06/17 Python
Python必须了解的35个关键词
2020/07/16 Python
python-图片流传输的思路及示例(url转换二维码)
2020/12/21 Python
python 实现百度网盘非会员上传超过500个文件的方法
2021/01/07 Python
家庭睡衣和家庭用品:Little Blue House
2018/03/18 全球购物
Manduka官网:瑜伽垫、瑜伽毛巾和服装
2018/07/02 全球购物
搬家公司的创业计划书
2014/01/01 职场文书
集团薪酬管理制度
2014/01/13 职场文书
社会实践活动总结范文
2014/07/03 职场文书
最美护士演讲稿
2014/08/27 职场文书
职工年度考核评语
2014/12/31 职场文书
居安思危观后感
2015/06/11 职场文书
写作之关于描写老人的好段摘抄
2019/11/14 职场文书
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js