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 ...
随机推荐
- LA 3135 优先队列
题目大意:有若干命令,它有两个属性Q_Num,Period(周期).按时间循序模拟前k个命令并输出他们的Q_Num,若同时发生输出Q_Num最小的值. #include<iostream> ...
- 数字梯形(cogs 738)
«问题描述:给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至底的路径.规则1:从梯形的顶 ...
- UVa294 Divisors
在一段区间[l,r]内,找出因数最多的数的个数以及其因数个数. 用唯一分解定理将一个数分解成质因数的乘积,例如 2^p1*3^p2*5^p3*7^p4*.... 从这些质因数中任选出一些数相乘,都可 ...
- 转载 gdb调试程序
转载自csdn,作者haoel,链接http://blog.csdn.net/haoel/article/details/2879 用GDB调试程序 GDB概述———— GDB是GNU开源组织发布的一 ...
- Python入门--6--今天抄袭人家一篇日志--numpy这个
Numpy NumPy的主要对象是同种元素的多维数组. 这是一个所有元素都是同一类型.通过一个正整数元祖索引的元素表格(通常元素都是数字) 在Numpy中维度(dimensions)叫做:轴 轴的个数 ...
- 1861 奶牛的数字游戏 2006年USACO
codevs——1861 奶牛的数字游戏 2006年USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题解 题目描述 Descript ...
- 【Todo】Java类型转换总结
参考 http://www.cnblogs.com/lwbqqyumidi/p/3700164.html 这篇文章也可以对照着看:http://www.360doc.com/content/10/09 ...
- 转: memcached Java客户端spymemcached的一致性Hash算法
转自:http://colobu.com/2015/04/13/consistent-hash-algorithm-in-java-memcached-client/ memcached Java客户 ...
- centos 7 -- Disk Requirements: At least 134MB more space needed on the / filesystem.
用了幾年的centos7,今天執行yum update時,彈出一行有錯誤的提示:Disk Requirements: At least 134MB more space needed on the ...
- HDU 4422 The Little Girl who Picks Mushrooms(数学)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=4422 Problem Description It's yet another festival s ...