深入浅析Vue中mixin和extend的区别和使用场景
作者:an3wer 发布时间:2024-05-29 22:42:43
Vue中有两个较为高级的静态方法mixin和extend,接下来我们来讨论下关于他们各自的原理和使用场景。
Mixin:
原理:
先来看看官网的介绍:
参数:{Object} mixin
用法:
混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用恰当时,这可以用来为自定义选项注入处理逻辑。
// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"我们知道,Vue.mixin传递的这个参数对象,在初始化Vue实例的时候会merge到options上,下面是Vue源码中对mixin的操作。
// src\core\global-api\mixin.js
export function initMixin (Vue: GlobalAPI) {
Vue.mixin = function (mixin: Object) {
this.options = mergeOptions(this.options, mixin)
return this
}
}
// src\core\instance\index.js
function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}
initMixin(Vue)
...
export default Vue
也就是说,mixin只是对我们在初始化Vue实例时传递的配置对象的一个扩展。
就像上面官网实例写的例子,我们在执行Vue.mixin方法时传递一个配置对象进去,对象里面有个created勾子函数,通过源码我们可以看到这个传递进来的对象最终会和我们在初始化实例也就是new Vue(options)
时的这个options合并(通过上面源码中的mergeOptions方法),保存在option上。
使用场景:
当我们需要全局去注入一些methods,filter或者hooks时我们就可以使用mixin来做。 比如我们希望每一个Vue实例都有一个print方法,我们就可以这么做:
Vue.mixin({
methods: {
print() {
console.log(`我是一个通过mixin注入的方法!`)
}
}
})
或者我们想要去监听在什么阶段时什么组件被加载了,被卸载了等等,我们可以这么做:
Vue.mixin({
mounted() {
console.log(`${this.$route.name} component mounted!`)
},
destroyed() {
console.log(`${this.$route.name} component destroyed!`)
}
})如果我们并不想给每一个组件实例都混入这些配置options,而只是个别的组件,最好不要使用mixin,它可能会影响到我们组件的性能。
Extend:
原理:
先来看看官网的介绍:
参数:{Object} options
用法:
使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
data 选项是特例,需要注意 - 在
Vue.extend()
中它必须是函数。data必须是函数是为了防止各个实例的数据混乱,闭包的应用。
<div id="mount-point"></div>
// 创建构造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')再来看看源码里面关于Vue.extend的实现:
Vue.extend = function (extendOptions: Object): Function {
extendOptions = extendOptions || {}
const Super = this
const SuperId = Super.cid
const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
if (cachedCtors[SuperId]) {
return cachedCtors[SuperId]
}
const name = extendOptions.name || Super.options.name
if (process.env.NODE_ENV !== 'production' && name) {
validateComponentName(name)
}
const Sub = function VueComponent (options) {
this._init(options)
}
Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
Sub.cid = cid++
Sub.options = mergeOptions(
Super.options,
extendOptions
)
Sub['super'] = Super
// For props and computed properties, we define the proxy getters on
// the Vue instances at extension time, on the extended prototype. This
// avoids Object.defineProperty calls for each instance created.
if (Sub.options.props) {
initProps(Sub)
}
if (Sub.options.computed) {
initComputed(Sub)
}
// allow further extension/mixin/plugin usage
Sub.extend = Super.extend
Sub.mixin = Super.mixin
Sub.use = Super.use
// create asset registers, so extended classes
// can have their private assets too.
ASSET_TYPES.forEach(function (type) {
Sub[type] = Super[type]
})
// enable recursive self-lookup
if (name) {
Sub.options.components[name] = Sub
}
// keep a reference to the super options at extension time.
// later at instantiation we can check if Super's options have
// been updated.
Sub.superOptions = Super.options
Sub.extendOptions = extendOptions
Sub.sealedOptions = extend({}, Sub.options)
// cache constructor
cachedCtors[SuperId] = Sub
return Sub
}
}
首先我们可以看到,extend方法返回的Sub其实是一个构造函数,而且继承自Vue,也就是说extend方法返回的是Vue的一个子类。
Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
这两行代码其实就是实现Sub对Vue的继承,源码中有一行是
const Super = this
所以这里的Super指的就是Vue。
Sub.options = mergeOptions(
Super.options,
extendOptions
)
我们注意到在extend中也会对传进来的配置option和Vue原来的options做一个合并。
使用场景:
当我们不需要全局去混入一些配置,比如,我们想要获得一个component。我们可以使用Vue.component(),
也可以使用Vue.extend()。
const ChildVue = Vue.extend({
...options
})
new ChildVue({
...options
})
注意extend得到的是一个Vue的子类,也就是构造函数。
区别:
mixin是对Vue类的options进行混入。所有Vue的实例对象都会具备混入进来的配置行为。
extend是产生一个继承自Vue类的子类,只会影响这个子类的实例对象,不会对Vue类本身以及Vue类的实例对象产生影响。
总结
以上所述是小编给大家介绍的Vue中mixin和extend的区别和使用场景,网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://juejin.im/post/5d4175a76fb9a06ae17d5589


猜你喜欢
- 开发环境安装最新版Python下载地址:https://www.python.org/downloads/运行Python1.交互方式运行用
- 使用keras进行训练,默认使用单显卡,即使设置了os.environ['CUDA_VISIBLE_DEVICES']为两张
- 如下所示:# -*- coding: utf-8 -*-import re#过滤掉除了中文以外的字符str = "hello,wo
- 微信网页授权认证根据微信官方文档,网页授权需要四个步骤, - 用户同意授权-获取code - 通过code 获取网页授权access_tok
- 前言在这篇文章中,准备用 Python 从头开始实现一个全连接的神经网络。你可能会问,为什么需要自己实现,有很多库和框架可以为我们做这件事,
- numpy.where (condition[, x, y])numpy.where() 有两种用法:1. np.where(conditi
- 正文开始if name == "main":可以看成是python程序的入口,就像java中的main()方法,但不完全
- 和大多数的语言脚本一样,学习ASP最好的方法就是亲身尝试ASP,使用你自己的系统安装PWS或者IIS。你可以边学习边在你自己的服务器上测试A
- Python3 正则表达式正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。本文主要阐述re包中的主要函数。
- python去除空格,tab制表符和\n换行符python中常用的替换字符串的函数有replace(),其用法相信大家都比较熟悉举个例子st
- yum or rpm?yum安装方式很方便,但是下载mysql的时候从官网下载,速度较慢。rpm安装方式可以从国内镜像下载mysql的rpm
- 本文介绍使用ADODB.Stream组件来下载服务器文件,例如:download.asp?file=相对路径的文件。就可以把这个文件下载下来
- 解决MySql 数据库 提示:1045 access denied for user 'root'@'localho
- 关于手机号码的提取,其实真正有用的部分就是re模块提供的正则表达式。使用正则表达式就能轻松地匹配到手机号码,由于功能比较简单这次并没有采用U
- wp_mail() 函数用来发送邮件,类似于 PHP 的 mail() 函数。默认的发件人名称是 WordPress,发件人邮箱是类似 wo
- 1.使用前先要安装 yagmailpip install yagmail -i https://pypi.douban.com/simple
- 如下所示:#!/usr/bin/env pythonimport serialimport timeimport threadclass M
- 我们经常会遇到数据库磁盘空间爆满的问题,或由于归档日志突增、或由于数据文件过多、大导致磁盘使用紧俏。这里主要说的场景是磁盘空间本身很大,但表
- 一、前言最近忙里偷闲,做了一个部署数据库及IIS网站站点的WPF应用程序工具。 二、内容此工具的目的是:根据.sql文件在本机上部
- var date = new Date('2016-11-11 11:11:11');document.write(date