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) //
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的更多相关文章

  1. Vue源码探究-全局API

    Vue源码探究-全局API 本篇代码位于vue/src/core/global-api/ Vue暴露了一些全局API来强化功能开发,API的使用示例官网上都有说明,无需多言.这里主要来看一下全局API ...

  2. Vue基础二之全局API、实例属性和全局配置,以及组件进阶(mixins)的详细教程(案列实现,详细图解,附源码)

    本篇文章主要是写Vue.directive().Vue.use()等常用全局API的使用,vm.$props.vm.$options.vm.$slots等实例属性的使用,以及Vue全局配置.组件的mi ...

  3. VUE 采坑之旅-- Mint-ui 按需引入报出Module build failed: Error: Couldn't find preset "es2015" relative to directory "C:\\phpStudy\\PHPTutorial\\WWW\\text\\vuep\\vue-demo"

    首先按照mint-ui的文档中按需引入的要求,先执行 npm install babel-plugin-component -D 然后,将.babelrc文件替换了,但是后来我又将其改了(采坑过程我也 ...

  4. vue 采坑

    1.ref 在父组件中访问子组件实例,或者直接操作DOM元素时需要ref <input ref="ipt"> 通过this.$refs.ipt 得到此input $re ...

  5. vue采坑及较好的文章汇总

    1:父子组件传动态传值 https://www.cnblogs.com/daiwenru/p/6694530.html  -----互传数据基本流程 https://blog.csdn.net/qq_ ...

  6. vue采坑之——vue里面渲染html 并添加样式

    在工作中,有次遇到要把返回的字符串分割成两部分,一部分用另外的样式显示. 这时候,我想通过对得到字符串进行处理,在需要特别样式的字符串片段用html标签(用的span)包裹起来再通过变量绑定就好了.不 ...

  7. vue采坑记录

    1.项目在浏览器运行的时候没有ico图标 <link rel="shortcut icon" type="image/x-icon" href=" ...

  8. Vue基础(环境配置、内部指令、全局API、选项、内置组件)

    1.环境配置 安装VsCode 安装包管理工具:直接下载 NodeJS 进行安装即可,NodeJS自带 Npm 包管理工具,下载地址:https://nodejs.org/en/download/安装 ...

  9. vue文档全局api笔记1

    全局api方法 1.Vue.extend(options) 请注意,extend创建的是一个组件构造器,而不是一个具体的组件实例.所以他不能直接在new Vue中这样使用: new Vue({comp ...

随机推荐

  1. 卸载完百度影音以后天气助手还在,而且总是自己主动打开ie浏览器,解决方式

    今天暴风影音不好用了.我就安装了百度影音,还有意外发现.相同的视频,用百度影音看不清楚,然后我就直接卸载了.结果卸掉以天气小助手还是在,而且总弹白色小框框,各种广告.最忍不了的是还自己主动打开ie浏览 ...

  2. Fragment进阶(四)-----&gt;參数传递3种写法

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  3. C#获取本机Sql Serverserver名

    private void Form2_Load(object sender, EventArgs e) { listBox1.Items.Clear(); SQLDMO.Application SQL ...

  4. element快速开发建站的动态UI------优

    网站快速成型工具 只为这样的你:  Element,一套为开发者.设计师和产品经理准备的基于 Vue 2.0 的组件库,提供了配套设计资源,帮助你的网站快速成型 http://element.elem ...

  5. python 46 盒模型 与盒模型布局

    一:盒模型 1.  盒模型的概念 广义盒模型:文档中所有功能性及内容性标签,及文档中显示性标签 侠义盒模型:文档中以块级形式存在的标签(块级标签拥有盒模型100%特性且最常用) 盒模型组成:margi ...

  6. CMake之CMakeLists.txt编写入门

    自定义变量 主要有隐式定义和显式定义两种. 隐式定义的一个例子是PROJECT指令,它会隐式的定义< projectname >_BINARY_DIR和< projectname & ...

  7. 【区间DP】释放囚犯

    貌似和石子合并差不多 可能是我见的题太少了,所以都差不多 OK 算法分析 首先不难看出这是一道区间DP,那么,按照本蒟蒻的意思 区间DP==三个循环 for(int len=2;len<=n;l ...

  8. HBase的集群搭建(1、3、5节点都适用)

    见 5 hbase-shell + hbase的java api

  9. 打开手机摄像头扫描二维码或条形码全部操作(代码写的不好,请提出指教,共同进步,我只是一个Android的小白)

    (1)下载二维码的库源码 链接:http://pan.baidu.com/s/1pKQyw2n 密码:r5bv 下载完成后打开可以看到 libzxing 的文件夹,最后添加进 Android  Stu ...

  10. php实现非对称加密

    <?php /** * 使用openssl实现非对称加密 * * @since 2015-11-10 */ class Rsa { /** * 私钥 * */ private $_privKey ...