Vue ref 和 v-for 结合(ref 源码解析)
前言
Vue 中组件的使用很方便,而且直接取组件实例的属性方法等也很方便,其中通过 ref 是最普遍的。
平时使用中主要是对一个组件进行单独设置 ref ,但是有些场景下可能是通过给定数据渲染的,这时会结合 v-for 一块使用。那么在使用的时候具体怎么写?为什么这样写?下面就来探究下。
一、ref 和 v-for 结合
1、ref 简单使用
// html
<div ref="testRef">
</div> // js
this.$refs.testRef.xxx
2、ref 结合 v-for 使用
<div :ref="'test'+t.code" v-for="t in classList" :key="t.code"></div>
在取值时怎么取?通过 this.$refs['test'+t.code]?
这样取会发现是一个数组,那就去数组中的第一使用(根据经验驱使),结果这样是对的。
this.$refs[`test${t.code}`][0]
用是用对了,那么为什么要这样用呢?我想在 Vue 源码中一定能够找到答案的。在 Vue 源码中的确找到了想要的。
二、Vue 中 ref 注册解析
直接在 ./src 下搜索 ref,搜索到的挺多的,一个个文件打开看了看,锁定了一个文件,这个文件就是 ref 的注册代码。(路径:src\core\vdom\modules\template-ref.ts)
这里主要看下文件中的 registerRef 函数:
export function registerRef(vnode: VNodeWithData, isRemoval?: boolean) {
const ref = vnode.data.ref
if (!isDef(ref)) return
const vm = vnode.context
const refValue = vnode.componentInstance || vnode.elm
const value = isRemoval ? null : refValue
const $refsValue = isRemoval ? undefined : refValue
if (isFunction(ref)) {
invokeWithErrorHandling(ref, vm, [value], vm, `template ref function`)
return
}
const isFor = vnode.data.refInFor
const _isString = typeof ref === 'string' || typeof ref === 'number'
const _isRef = isRef(ref)
const refs = vm.$refs
if (_isString || _isRef) {
// 这里就是 v-for 绑定时的处理
if (isFor) {
const existing = _isString ? refs[ref] : ref.value
if (isRemoval) {
isArray(existing) && remove(existing, refValue)
} else {
if (!isArray(existing)) {
if (_isString) {
refs[ref] = [refValue]
setSetupRef(vm, ref, refs[ref])
} else {
ref.value = [refValue]
}
} else if (!existing.includes(refValue)) {
existing.push(refValue)
}
}
} else if (_isString) {
if (isRemoval && refs[ref] !== refValue) {
return
}
refs[ref] = $refsValue
setSetupRef(vm, ref, value)
} else if (_isRef) {
if (isRemoval && ref.value !== refValue) {
return
}
ref.value = value
} else if (__DEV__) {
warn(`Invalid template ref type: ${typeof ref}`)
}
}
}
1、函数可以绑定 ref 的值,也可以删除
2、根据传入的 node 的 ref 绑定值的类型:string、number、ref、InFor 做不同的处理
3、如果是 InFor 绑定的 ref ,会存储成数组的方式
所以,到此从源码中找到 ref 在绑定时,如果是通过 v-for 绑定的,那么 ref.value 就是数组,在取值时就要按照数组方式取值了。
Vue ref 和 v-for 结合(ref 源码解析)的更多相关文章
- 【vuejs深入二】vue源码解析之一,基础源码结构和htmlParse解析器
写在前面 一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. vuejs是一个优秀的前端mvvm框架,它的易用性和渐进式的理念可以使每一个前端开发人员感到舒服,感到easy.它内 ...
- 【vuejs深入三】vue源码解析之二 htmlParse解析器的实现
写在前面 一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. 昨天博主分析了一下在vue中,最为基础核心的api,parse函数,它的作用是将vue的模板字符串转换成ast,从而 ...
- vue UI库iview源码解析(2)
上篇问题 在上篇<iview源码解析(1)>中的index.js 入口文件的源码中有一段代码有点疑惑: /** * 在浏览器环境下默认加载组件 */ // auto install if ...
- Vue源码解析---数据的双向绑定
本文主要抽离Vue源码中数据双向绑定的核心代码,解析Vue是如何实现数据的双向绑定 核心思想是ES5的Object.defineProperty()和发布-订阅模式 整体结构 改造Vue实例中的dat ...
- Vue源码解析之数组变异
力有不逮的对象 众所周知,在 Vue 中,直接修改对象属性的值无法触发响应式.当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变. 这是什么原因? 原因在于: Vue 的响应式 ...
- Vue源码解析之nextTick
Vue源码解析之nextTick 前言 nextTick是Vue的一个核心功能,在Vue内部实现中也经常用到nextTick.但是,很多新手不理解nextTick的原理,甚至不清楚nextTick的作 ...
- vue系列---响应式原理实现及Observer源码解析(一)
_ 阅读目录 一. 什么是响应式? 二:如何侦测数据的变化? 2.1 Object.defineProperty() 侦测对象属性值变化 2.2 如何侦测数组的索引值的变化 2.3 如何监听数组内容的 ...
- 【VUE】Vue 源码解析
Vue 源码解析 Vue 的工作机制 在 new vue() 之后,Vue 会调用进行初始化,会初始化生命周期.事件.props.methods.data.computed和watch等.其中最重要的 ...
- Vue源码解析:AST语法树转render函数
开始 今天要说的代码全在codegen文件夹中,在说实现原理前,还是先看个简单的例子! <div class="container"> <span>{{ms ...
- Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例
概要 这一章,我们对WeakHashMap进行学习.我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap.第1部分 WeakHashMap介绍 ...
随机推荐
- Canvas 线性图形(三):曲线
前言 画曲线要用到二次贝塞尔曲线或三次贝塞尔曲线.贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如 PhotoShop. 二次贝塞尔曲线 二次贝塞尔曲线在 ...
- Java jdk常用工具集合
jdk 常用工具包目录: windows: 默认安装目录:C:\Program Files\Java\jdk1.8.0_152\bin> 1.查看Java进程 jps -l 查看当前机器的Jav ...
- B2. Wonderful Coloring - 2
链接:Problem - 1551B2 - Codeforces 题意:有m个颜色,要求每种颜色内的数字各不相同,问,颜色的最大长度多少. 题解: 判断每个数字的个数,如果大于m,那么最大长度就加一 ...
- 说说 JSON 格式的弊端与解决方法
JSON 格式是目前最流行的数据交互格式,广泛应用于前后端分离的系统.但也有一些场合不适合使用 JSON 格式. 1 JSON 格式弊端 有这样的一个需求:希望把客户端的日志上传到服务器存储起来.原先 ...
- Linux配置bond模式 双网卡绑定步骤
什么是bond 网卡bond是通过多张网卡绑定为一个逻辑网卡,实现本地网卡的冗余,带宽扩容和负载均衡,在生产场景中是一种常用的技术.Kernels 2.4.12及以后的版本均供bonding模块,以前 ...
- 通过VS下载的NuGet包,如何修改其下载存放路径?
一.了解NuGet包的默认存放路径 我们通过NuGet包管理器下载的引用包,默认是存放在C盘的,存储路径一般是: C:\Users\{系统用户名}\.nuget\packages 我们都知道,C盘的存 ...
- 高阶 CSS 技巧在复杂动效中的应用
最近我在 CodePen 上看到了这样一个有意思的动画: 整个动画效果是在一个标签内,借助了 SVG PATH 实现.其核心在于对渐变(Gradient)的究极利用. 完整的代码你可以看看这里 -- ...
- Spring Boot2配置Swagger2生成API接口文档
一.Swagger2介绍 前后端分离开发模式中,api文档是最好的沟通方式. Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 及时性 (接 ...
- AOP实现系统告警
工作群里的消息怕过于安静,又怕过于频繁 一.业务背景 在开发的过程中会遇到各种各样的开发问题,服务器宕机.网络抖动.代码本身的bug等等.针对代码的bug,我们可以提前预支,通过发送告警信息来警示我们 ...
- 萌新码农的第一篇:MarkDown的使用方法
MarkDown的使用方法 使用的编辑软件Typora 1.标题的使用方法 输入''#''然后空格,输入标题名字即可生成标题. 随着''#''的增多,标题的大小会依次减小,最多到六级标题 2.排字 字 ...