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) //
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的更多相关文章
- Vue源码探究-全局API
Vue源码探究-全局API 本篇代码位于vue/src/core/global-api/ Vue暴露了一些全局API来强化功能开发,API的使用示例官网上都有说明,无需多言.这里主要来看一下全局API ...
- Vue基础二之全局API、实例属性和全局配置,以及组件进阶(mixins)的详细教程(案列实现,详细图解,附源码)
本篇文章主要是写Vue.directive().Vue.use()等常用全局API的使用,vm.$props.vm.$options.vm.$slots等实例属性的使用,以及Vue全局配置.组件的mi ...
- 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文件替换了,但是后来我又将其改了(采坑过程我也 ...
- vue 采坑
1.ref 在父组件中访问子组件实例,或者直接操作DOM元素时需要ref <input ref="ipt"> 通过this.$refs.ipt 得到此input $re ...
- vue采坑及较好的文章汇总
1:父子组件传动态传值 https://www.cnblogs.com/daiwenru/p/6694530.html -----互传数据基本流程 https://blog.csdn.net/qq_ ...
- vue采坑之——vue里面渲染html 并添加样式
在工作中,有次遇到要把返回的字符串分割成两部分,一部分用另外的样式显示. 这时候,我想通过对得到字符串进行处理,在需要特别样式的字符串片段用html标签(用的span)包裹起来再通过变量绑定就好了.不 ...
- vue采坑记录
1.项目在浏览器运行的时候没有ico图标 <link rel="shortcut icon" type="image/x-icon" href=" ...
- Vue基础(环境配置、内部指令、全局API、选项、内置组件)
1.环境配置 安装VsCode 安装包管理工具:直接下载 NodeJS 进行安装即可,NodeJS自带 Npm 包管理工具,下载地址:https://nodejs.org/en/download/安装 ...
- vue文档全局api笔记1
全局api方法 1.Vue.extend(options) 请注意,extend创建的是一个组件构造器,而不是一个具体的组件实例.所以他不能直接在new Vue中这样使用: new Vue({comp ...
随机推荐
- 4、angularJS过滤器
一.过滤器的作用 过滤器用来格式化须要展示给用户的数据. 在HTML中的模板绑定符号{{ }}内通过|符号来调用过滤器. 比如.如果我们希望将字符串转换成大写能够对字符串中的每一个字符都单独进行转换操 ...
- POJ 2421--Constructing Roads【水题 && 最小生成树 && kruskal】
Constructing Roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 20889 Accepted: 88 ...
- Oracle 静态监听注冊具体解释
Oracle 静态监听注冊具体解释 网上有非常多关于oracle 监听静态注冊的文章.但大多都是简单说说,并没有具体的样例.这里,将结合linux as4 下的oracle 10gR2.0.1 举一个 ...
- PCB Windows远程桌面一键登录
开发时会经常需远程操作服务器,每次运行再也熟悉不过的命令 mstsc 或 mstsc -v 120.79.36.65 远程到目标服务器, 每次需输入密码,弹出烦人的 如何免密码一键登录呢,其实微软已 ...
- Netty引导流程解读
Channel的生命周期状态[状态转换将变为相应的事件,转发给ChannelPipeline中的ChannelHandler进行处理] ChannelUnregistered:Channel已经被创建 ...
- Windows7下caffe-ssd-microsoft下编译
整个编译可谓漫长 编译了两天 网上教程也很多 但是也很杂 遇到各种错误 总归是编完了 1.下载Windows版本的Caffe-SSD源码 下载链接:https://github.com/conner9 ...
- mybatis 传map参数
第一步在你的mapper写上: List<WeixinUserLocationList> findweixinUserLocations(@Param("params" ...
- Spring Boot (6) Spring Data JPA
JPA 全称Java Persistence API,JPA通过JDK 5.0注解或xml描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中 JPA是sun官方提出的java持久化规范, ...
- C#调用FFMPEG实现桌面录制(视频+音频+生成本地文件)
不得不说FFMPEG真是个神奇的玩意,所接触的部分不过万一.网上有个很火的例子是c++方面的,当然这个功能还是用c++来实现比较妥当. 然而我不会c++ 因为我的功能需求比较简单,只要实现基本的录制就 ...
- Assembly之instruction之Indirect Autoincrement Mode
Assembler Code Content of ROMMOV @R10+,0(R11) MOV @R10+,0(R11) Length: One or two words Operation: ...