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 ...
随机推荐
- [暑假集训--数位dp]hdu2089 不要62
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍, ...
- uva 11178二维几何(点与直线、点积叉积)
Problem D Morley’s Theorem Input: Standard Input Output: Standard Output Morley’s theorem states tha ...
- Count on a tree(bzoj 2588)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- POJ 3104 Drying [二分 有坑点 好题]
传送门 表示又是神题一道 Drying Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9327 Accepted: 23 ...
- IntelliJ IDEA 使用的问题总结
第一个问题:idea 无法创建springboot的项目 1. 点击IDEA setting之后,找到Http Proxy 选择Atuo-detect proxy settings 之后点击 ...
- android 获得系统时间
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...
- 【IntelliJ Idea】启动参数JVM参数的配置 优先级高于 application.yaml/application.properties中的配置,前者可以覆盖后者的配置
- MyReport报表引擎1.2.0.1新功能
一维码(Code128B)转换显示. 多联标题. 修正BugSum统计函数问题报表编辑器保存时没有生成新加入的单元格相关的xml数据 相关链接MyReport演示.产品站点 相关文章MyReport ...
- BUPT复试专题—哈夫曼树(2010)
https://www.nowcoder.com/practice/162753046d5f47c7aac01a5b2fcda155?tpId=67&tqId=29635&tPage= ...
- CentOS下常用的 19 条命令
玩过Linux的人都会知道,Linux中的命令的确是非常多,但是玩过Linux的人也从来不会因为Linux的命令如此之多而烦恼,因为我们只需要掌握我们最常用的命令就可以了.当然你也可以在使用时去找一下 ...