vue采坑一:全局API
Posted web_study
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue采坑一:全局API相关的知识,希望对你有一定的参考价值。
Vue.set
Vue.set( target, key, value ),target不能是 Vue 实例,或者 Vue 实例的根数据对象,因为源码中做了如下判断:
var ob = (target).__ob__; if (target._isVue || (ob && ob.vmCount)) { "development" !== \'production\' && warn( \'Avoid adding reactive properties to a Vue instance or its root $data \' + \'at runtime - declare it upfront in the data option.\' ); return val }
target._isVue阻止了给Vue实例添加属性,ob && ob.vmCount阻止了给Vue实例的根数据对象添加属性。
Vue.delete
如果Vue能检测到delete操作,那么就不会出现这个api。如果一定要用delete来删除$data的属性,那就用Vue.delete,否则不会触发dom的更新。
同Vue.set,Vue.delete( target, key )的target不能是一个 Vue 示例或 Vue 示例的根数据对象。源码中的阻止方式和Vue.set相同。
在2.2.0+ 版本中target若为数组,key则是数组下标。因为Vue.delete删除数组实际是用splice来删除,delete虽然能用于删除数组,但位置还在,不能算真正的删除。
var a = [1, 2, 3]; delete a[0]; console.log(a); // [undefined, 2, 3]
Vue.use
Vue.use 源码比较简单,可以全部贴出来。
Vue.use = function (plugin) { var installedPlugins = (this._installedPlugins || (this._installedPlugins = [])); if (installedPlugins.indexOf(plugin) > -1) { return this } // additional parameters var args = toArray(arguments, 1); args.unshift(this); if (typeof plugin.install === \'function\') { plugin.install.apply(plugin, args); } else if (typeof plugin === \'function\') { plugin.apply(null, args); } installedPlugins.push(plugin); return this };
安装的插件放到了 installedPlugins ,安装插件前通过installedPlugins.indexOf(plugin)来判断插件是否被安装过,进而阻止注册相同插件多次。
插件类型为 object,必须指定 install 属性来安装插件(typeof plugin.install === \'function\'),另外插件执行采用plugin.install.apply(plugin, args);,因此 this 访问 object 的其他属性。此处的 args 是由 Vue(args.unshift(this);) 和 Vue.use 传入的除了 plugin 的其他参数(toArray(arguments, 1),1 表示从 arguments[1] 开始截取)。
Vue.use({ a: 1, install: function (Vue) { console.log(this.a) // 1 console.log(arguments) // [function Vue(options),"a", "b", "c"] } }, \'a\', \'b\', \'c\')
插件类型为 function,安装调用plugin.apply(null, args);,因此在严格模式下插件运行时上下文 this 为 null,非严格模式为 Window。
\'use strict\' Vue.use(function plugin() { console.log(this) // null console.log(arguments) // [function Vue(options),"a", "b", "c"] }, \'a\', \'b\', \'c\')
Vue.extend
配置项data必须为function,否则配置无效。data的合并规则源码如下:
strats.data = function ( parentVal, childVal, vm ) { if (!vm) { if (childVal && typeof childVal !== \'function\') { "development" !== \'production\' && warn( \'The "data" option should be a function \' + \'that returns a per-instance value in component \' + \'definitions.\', vm ); return parentVal } return mergeDataOrFn(parentVal, childVal) } return mergeDataOrFn(parentVal, childVal, vm) };
传入非function类型的data(上图中data配置为{a:1}),在合并options时,如果data不是function类型,开发版会发出警告,然后直接返回了parentVal,这意味着extend传入的data选项被无视了。
我们知道实例化Vue的时候,data可以是对象,这里的合并规则不是通用的吗?注意上面有个if(!vm)的判断,实例化的时候vm是有值的,因此不同于Vue.extend,其实下面的注释也做了说明(in a Vue.extend merge, both should be function),这也是官方文档为何说data是个特例。
另外官方文档所说的“子类”,是因为Vue.extend返回的是一个“继承”Vue的函数,源码结构如下:
Vue.extend = function (extendOptions) { //*** var Super = this; var SuperId = Super.cid; //*** var Sub = function VueComponent(options) { this._init(options); }; Sub.prototype = Object.create(Super.prototype); Sub.prototype.constructor = Sub; //*** return Sub
以上是关于vue采坑一:全局API的主要内容,如果未能解决你的问题,请参考以下文章