ref 与 $refs 如何关联
先问大家一个简单的问题:
还有人记得 jquery 里面的 data 方法是如何让
DOM 节点
绑定对应的数据对象
的吗
有时候我们做节点关联
设计的思路其实有一点类似,但是在 vue 里面多了很多概念,比如:
1、vnode
: 如何生成的,包含子父关系、属性 data
2、内置的 ref
对象的 create
如何注册
3、生命周期
:解析到根节点之后获取 outerHTML
再一步一步解析子元素
用惯 vue
的人都会很熟悉地:
使用 ref 来注册引用信息,再通过
$refs
对象就可以做关联
但是我们看看它们是如何关联上
的呢?
代码片段来自 2.5.16
版本:
1、需要初始化 $refs
,默认是一个空对象
我们看到在函数 initLifecycle
上会往 vm
上设置一个 key 为 $refs 值为一个对象
function initLifecycle (vm) {
vm.$refs = {};
}
2、获取元素
上的 ref
值:
在函数 registerRef
上,它接受 2
个参数:
- vnode
- isRemoval
function registerRef (vnode, isRemoval) {}
直接通过 vnode.data
获取:
var key = vnode.data.ref;
然后获取 $refs
在这之前需要获取 vm
:
从 vnode 上下文 context 获取
var vm = vnode.context;
然后很简单的就是 vm.$refs
var refs = vm.$refs;
ref 其实是什么呢?
DOM 节点或组件实例
这里的:
- componentInstance -- 组件实例
- elm -- DOM 节点
var ref = vnode.componentInstance || vnode.elm;
这里需要处理一下 v-for 一起用的情况,官网也提过:
对应的引用信息是包含 DOM 节点或组件实例的
数组
if (vnode.data.refInFor) {}
情况一:如果不是数组格式,强制
转换一下,外层套一个数组
判断方式:Array.isArray
if (!Array.isArray(refs[key])) {
refs[key] = [ref];
}
情况二:看数组里面是否存在
当前这个 ref,如果不存在,push
进去
if (refs[key].indexOf(ref) < 0) {
refs[key].push(ref);
}
如果不是和 v-for 一起用:直接设置对象的 key 和 value:
refs[key] = ref;
最后一个问题,官网提到了:
ref 注册时间 -- 因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在
那我们看看:
1、它到底是在什么时机绑定的
2、vnode 是如何产生的
最开始我们从 _init
开始
Vue.prototype._init = function (options) {
// vm.$mount
if (vm.$options.el) {
vm.$mount(vm.$options.el);
}
}
生成 vnode 最核心的部分:
实例化 VNode
function _createElement (
var vnode;
if (typeof tag === 'string') {
// ...
vnode = new VNode(
config.parsePlatformTagName(tag), data, children,
undefined, undefined, context
);
}
}
我们以如下代码为例:
<div id="app">
<img ref="imgbox" src="https://vuejs.org/images/logo.png" alt="Vue logo">
</div>
我们的 VNode 如下:
最外层 app 转换的 vnode:
children:[VNode]
data: {
attrs: {
id: "app"
}
}
tag: "div"
子 vnode 如下:
data: {
ref: "imgbox",
attrs: {
src:"https://vuejs.org/images/logo.png",
alt:"Vue logo"
}
}
tag: "img"
内置了一个 ref 对象,里面有 create 函数,调用了 registerRef
var ref = {
create: function create (_, vnode) {
registerRef(vnode);
}
}
在函数 invokeCreateHooks
调用 create
注意两点:
1、cbs
是什么?
2、create
又是什么,和 ref
对象的 create
有什么关系
function invokeCreateHooks (vnode, insertedVnodeQueue) {
for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {
cbs.create[i$1](emptyNode, vnode);
}
}
后面会提到:hooks
var hooks = ['create', 'activate', 'update', 'remove', 'destroy'];
核心部分:createPatchFunction
,往 cbs
里面放置对应的函数
function createPatchFunction (backend) {
var cbs = {};
var modules = backend.modules;
for (i = 0; i < hooks.length; ++i) {
cbs[hooks[i]] = [];
for (j = 0; j < modules.length; ++j) {
// ...
cbs[hooks[i]].push(modules[j][hooks[i]]);
}
}
}
那谁调用了 createPatchFunction
函数呢:
var modules = platformModules.concat(baseModules);
var patch = createPatchFunction({ nodeOps: nodeOps, modules: modules });
我们发现 baseModules
关联了 ref
var baseModules = [
ref,
directives
]
来源:https://segmentfault.com/a/1190000016323531
ref 与 $refs 如何关联的更多相关文章
- vue.js中ref及$refs的使用及讲解
关于ref和$refs的用法及讲解,vue.js中文社区( https://cn.vuejs.org/v2/api/#ref )是这么讲解的: ref 被用来给元素或子组件注册引用信息,引用信息将会注 ...
- vue中的 ref 和 $refs
如图,ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向组件实例: ...
- vue的ref与$refs
一. ref使用在父组件上 父组件html: <information ref='information'></information> import information ...
- ref、refs使用的注意事项
ref是被用来给元素或子组件注册引用信息.引用信息将注册在父组件的 $refs 对象身上.如果在普通的DOM元素身上使用,引用指向就是DOM元素:如果用在子组件身上,引用就是指向组件实例. 当v-fo ...
- Vue 获取dom元素之 ref 和 $refs 详解
一.$refs 一个对象,持有ref注册过的所有元素或子组件.(注册过的 ref 的集合) 二.ref 被用来给元素或子组件注册引用信息.若用在dom元素上,引用指向的就是dom元素:若用在子组件上, ...
- 理解Vue中的ref和$refs
参考博客:https://www.cnblogs.com/xumqfaith/p/7743387.html
- Vue 中的 ref $refs
ref 被用来给DOM元素或子组件注册引用信息.引用信息会根据父组件的 $refs 对象进行注册.如果在普通的DOM元素上使用,引用信息就是元素; 如果用在子组件上,引用信息就是组件实例 注意:只要想 ...
- vue特殊属性 key ref slot
1.key 当使用key时,必须设置兄弟元素唯一的key,当key排列顺序变化时,兄弟元素会重新排列,而当key的值变化时,这个元素会被重新渲染. 有相同父元素的子元素必须有独特的 key.重复的 k ...
- oracle ref游标
Oracle 系列:REF Cursor 在上文 Oracle 系列:Cursor (参见:http://blog.csdn.net/qfs_v/archive/2008/05/06/240479 ...
随机推荐
- 黑匣子_NOI导刊2010提高 (对顶堆)
题目描述 Black Box是一种原始的数据库.它可以储存一个整数数组,还有一个特别的变量i.最开始的时候Black Box是空的.而i等于0.这个Black Box要处理一串命令. 命令只有两种: ...
- 转载: LINK : fatal error LNK1104: 无法打开文件“mfc71.lib”的原因又一例
转载地址:http://blog.csdn.net/mxclxp/article/details/8196142 LINK : fatal error LNK1104: 无法打开文件“mfc71.li ...
- 欧拉函数(codevs 4939)
题目描述 Description 输入一个数n,输出小于n且与n互素的整数个数 输入描述 Input Description 包含多组数据,n=0时结束 测试数据组数不会很多,不必先打表后输出 输出描 ...
- Codeforces Round #275 (Div. 2) B. Friends and Presents 二分+数学
8493833 2014-10-31 08:41:26 njczy2010 B - Friends and Presents G ...
- Mac快速查看隐藏文件
使用终端 显示隐藏文件的最简单方法是使用终端.只要打开终端(位于应用程序--实用工具),将以下代码复制进去然后回车 defaults write com.apple.finder AppleShowA ...
- Delphi中的操作二进制文件的两个重要函数
Delphi中的操作二进制文件的两个重要函数 对于通过Byte数组进行文件操作的,在FTP中经常会使用到,我也是在Delphi调用Web Service进行文件的上传和下载时找到这两个函数的,挺好用的 ...
- 模板题 Problem I Link Cut Tree
@(XSY)[LCT] Description 你们这么轻松A了前两题,要是AK了我可就惨了,所以这道题一定要是难(shui)题.那出什么难题呢?有了,这样吧,第一题是数,第二题是树,那我就出个同时含 ...
- Win10激活Office2013的技巧
原文:http://www.xitongzhijia.net/xtjc/20150720/53252.html KMSpico Win10激活工具 是一款能激活Win8/Win8.1/win10/Of ...
- 天下文章一大抄 之 修改excel 创建时间
Sub ChangeDate()ThisWorkbook.BuiltinDocumentProperties("Creation Date") = #2 28 2016 13:25 ...
- 转:使用 SCons 轻松建造程序
转: https://www.ibm.com/developerworks/cn/linux/l-cn-scons/ 在软件项目开发过程中,make 工具通常被用来建造程序.make 工具通过一个被称 ...