一、前言

  在之前的前端开发中,为了实现我们的需求,通常采用的方案是通过 JS/Jquery 直接操纵页面的 DOM 元素,得益于 Jquery 对于 DOM 元素优异的操作能力,我们可以很轻易的对获取到的 DOM 元素进行操作。但是,当我们开始在前端项目中使用 Vue 这类的 MVVM 框架之后,对于 DOM 的操作我们就应当完全的交给框架,而我们只需要关注于数据。难道,在 Vue 中就不能手动获取到页面上的 DOM 元素了吗,答案当然是可以手动获取到 DOM 元素的,在 Vue 中我们可以通过使用 ref 实现获取 DOM 元素的功能,当然,这也只是 ref 其中一项的功能。本章,我们就来学习 Vue 中 ref 的相关使用。

  学习系列目录地址:https://www.cnblogs.com/danvic712/p/9549100.html

  仓储地址:https://github.com/Lanesra712/VueTrial/blob/master/chapter02-bronze/ref.html

二、干货合集

  ref 在 Vue 中是用来给元素或是子组件注册引用信息到父组件或是 Vue 实例上,注册后的引用信息都会呈现在父组件/Vue 实例的 $.refs 上,这时,我们就可以通过 $.refs 获取到引用的 DOM 对象或是子组件信息。

  例如,我们可以获取到页面上添加了 ref 的 input 输入框的值,对于子组件来说,我们可以直接获取到子组件 data 选项中的数据,或是直接调用子组件的方法。

  1、虚拟 DOM

  在我们使用 JS/Jquery 直接对 DOM 元素进行操作时,不管是对元素样式的修改(背景颜色从红色变成蓝色)还是对页面中的某些布局进行动态调整(通过点击按钮在列表中添加一行新的数据),这都会造成页面的重新渲染,从而影响我们网站的性能。而在 Vue 中,通过在内存中生成与真实 DOM 与之对应的数据结构(虚拟 DOM),当页面发生变化时,通过新的虚拟 DOM 树与旧的虚拟 DOM 树进行比对,就能很快的找出差异点,从而得出应施加到真实 DOM 上的改动。

  2、使用 ref 获取页面 DOM 元素

  在使用 JS/Jquery 获取页面的 DOM 元素时,我们一般是根据 id、class、标签、属性等其它标识来获取到页面上的 DOM 元素。嗯,可以说,我们很难抛弃 Jquery 的一个重大原因,就是当我们需要获取到页面上的 DOM 元素时,使用 Jquery 的 API 相比于原生的 JS 代码,简单到极致,有木有。

document.getElementById('id').value => $('#id').val()

  那么,难道我们在 Vue 中获取 DOM 元素还是采用这样的方式?

  答案当然是否定的,这种直接操纵 DOM 元素的方式,与我们使用 Vue 的初衷不符,虽然能达成效果,但是却不提倡,这里我们就可以使用 ref 来获取页面上的 DOM 元素。

  在下面的代码中,我在 input 上添加了一个 ref 属性,之后,我们就可以在 Vue 实例中获取到这个 input 输入框的值。这里,我在 beforeMount、mounted 这两个 Vue 中的生命周期钩子函数以及一个按钮的点击事件中尝试获取到这个 input 输入框的值。

<div id="app">
<input type="text" ref="msgText" v-model="msg" />
<button @click="getElement">获取元素值</button>
</div> <script>
var vm = new Vue({
el: "#app",
data: {
msg: 'Hello ref'
},
beforeMount() {
console.log('beforeMount: ' + this.$refs.msgText.value)
},
mounted() {
console.log('mounted: ' + this.$refs.msgText.value)
},
methods: {
getElement() {
console.log(this.$refs.msgText.value)
}
}
});
</script>

  运行代码,从结果中可以看到,在 beforeMount 这个钩子函数中,我们是无法获取到这个 DOM 元素的值,结合之前学习的 Vue 生命周期的相关知识,当执行到 beforeMount 钩子函数时,Vue 虽然已经将模板编译完成,但是尚未挂载到页面 DOM 元素上,因此我们可以得出 ref 是在页面渲染完成后才被创建的。

  可以看到,当我们在 input 输入框中添加了 ref 属性后,在当前的 Vue 实例的 $.refs 上就挂载了当前的 input 框对象。

  3、使用 ref 获取子组件对象

  同使用 ref 获取页面的 DOM 元素相似,当我们需要获取子组件时,只需要将使用到子组件上的地方添加 ref 属性即可。在下面的示例代码中,我添加了一个子组件,当我们点击 Vue 实例上的按钮时,会先调用子组件的方法,然后获取子组件的数据。

<div id="app">
<input type="text" ref="msgText" v-model="msg" />
<button @click="getElement">获取元素值</button> <hr> <child ref="childComponent"></child>
</div> <template id="child">
<div>
<input type="datetime" name="datetime" v-model="local">
<button @click="getLocalData">获取当前时间</button>
</div>
</template> <script>
var vm = new Vue({
el: "#app",
data: {
msg: 'Hello ref'
},
mounted() {
console.log('mounted: ' + this.$refs.msgText.value)
},
methods: {
getElement() {
console.log('input 输入框的值为:' + this.$refs.msgText.value)
this.$refs.childComponent.getLocalData()
console.log('子组件 input 输入框的值为:' + this.$refs.childComponent.local)
}
},
components: {
'child': {
template: '#child',
data() {
return {
local: ''
}
},
methods: {
getLocalData() {
var date = new Date()
this.local = date.toLocaleString()
}
},
}
}
});
</script>

  可以看到,当我们将 ref 添加到子组件上,我们就可以在 Vue 实例上获取到这个注册的组件引用,同注册的 DOM 元素一样,我们都可以使用添加的 ref 属性值作为 key 获取到注册的对象。此时,我们就可以获取到这个子组件上的 data 选项和 methods 选项。

三、总结

  因为 Vue 采用 Virtual DOM 的做法渲染网页,如果我们直接操作 DOM,很容易产生实际网页跟 Vue 产生的 Virtual DOM 不同步的问题,而通过使用 ref 属性之后,在一些需要获取 DOM 元素的情况下,我们就可以很方便的获取 DOM 元素。当然,当我们决定在项目中使用 Vue,还是需要转变我们的思路,将操作 DOM 转变成操作数据。同样的,通过将 ref 属性添加到子组件上,我们就可以很轻松的获取到子组件的相关信息,这无疑给父组件获取子组件数据、调用子组件的方法提供了一种新的思路。

四、参考

  1、网页性能管理详解

  2、重排重绘,看这一篇就够了

  3、Vue作者尤雨溪:Vue 2.0,渐进式前端解决方案

  4、vue中的 ref 和 $refs

Vue.js-11:第十一章 - Vue 中 ref 的使用的更多相关文章

  1. VUe.js 父组件向子组件中传值及方法

    父组件向子组件中传值 1.  Vue实例可以看做是大的组件,那么在其内部定义的私有组件与这个实例之间就出现了父子组件的对应关系. 2. 父子组件在默认的情况下,子组件是无妨访问到父组件中的数据的,所以 ...

  2. 【Vue.js】简单说下vuejs中v-model自定义使用姿势

    vue.js中有个v-model的语法,可以实现双向绑定. 起初刚看到的时候,觉得很神奇.后面随着对vue.js的熟悉.发现这个其实是vue官方给我们实现的一个语法糖. 使用v-model的时候,vu ...

  3. Vue.js-07:第七章 - Vue 实例的生命周期

    一.前言  在之前的 Vue 学习中,我们在使用 Vue 时,都会创建一个 Vue 的实例,而每个 Vue 实例在被创建时都要经过一系列的初始化过程.例如,需要设置数据监听.编译模板.将实例挂载到 D ...

  4. Vue.js(25)之 vue全局配置api介绍

    本文介绍的全局api并不在Vue的构造函数内,而是在Vue构造器外面提供这些方法,让我们扩展新功能. 1. vue.extend(options) 参考:https://www.w3cplus.com ...

  5. vue.js not detected 解决办法-vue.js devtools 安装

    国外网站:https://www.crx4chrome.com/ 国内网站:http://www.cnplugins.com/ http://chromecj.com/web-development/ ...

  6. Vue.js 系列教程 3:Vue

    原文:intro-to-vue-3-vue-cli-lifecycle-hooks 译者:nzbin 这是 JavaScript 框架 Vue.js 五篇教程的第三部分.在这一部分,我们将学习 Vue ...

  7. Vue.js—组件快速入门及Vue路由实例应用

    上次我们学习了Vue.js的基础,并且通过综合的小实例进一步的熟悉了Vue.js的基础应用.今天我们就继续讲讲Vue.js的组件,更加深入的了解Vue,js的使用.首先我们先了解一下什么是Vue.js ...

  8. vue.js初学(一) vue的入门编程

    1:首先引入vue.js 2:点击事件 <div id='clickVue'> <p>{{message}}</p> <button v-on:click=& ...

  9. [Vue 牛刀小试]:第十三章 - Vue Router 基础使用再探(命名路由、命名视图、路由传参)

    一.前言 在上一章的学习中,我们简单介绍了前端路由的概念,以及如何在 Vue 中通过使用 Vue Router 来实现我们的前端路由.但是在实际使用中,我们经常会遇到路由传参.或者一个页面是由多个组件 ...

随机推荐

  1. 利用redis自制幻灯片弹幕

    前段时间赶项目,忙结婚,各大技术平台都没时间上,不过还是抽出点时间为自己的婚礼做了一点小玩具,今天我就来给大家分享一下. 先来看一下效果 这个项目是基于微信个人订阅号的,订阅号的开发在此我就不再赘述了 ...

  2. git命令行常用几个指令(细节问题)

    GIT PUSH/PULL时总需要输入用户名密码的解决方案: git config --global credential.helper store 查看当前的配置信息: git config --s ...

  3. Beta 冲刺day2

    1.昨天的困难,今天解决的进度,以及明天要做的事情 昨天的困难:昨天主要是在确认需求方面花了一些时间,后来终于确认了企业自查风险模块的需求问题 今天解决的进度:根据昨天确认下来的需求,我们基本上完成了 ...

  4. MapReduce的架构及原理

    MapReduce是一种分布式计算模型,是Hadoop的主要组成之一,承担大批量数据的计算功能.MapReduce分为两个阶段:Map和Reduce. 一.MapReduce的架构演变 客户端向Job ...

  5. sniffer 简介

    http://www.doc88.com/p-095375416629.html 介绍sniffer的工作原理及简单介绍.

  6. 杨老师课堂_Java核心技术下之控制台模拟微博用户注册案例

    案例设计背景介绍: 编写一个新浪微博用户注册的程序,要求使用HashSet集合实现.  假设当用户输入用户名.密码.确认密码.生日(输入格式yyyy-mm-dd为正确).手机号码(手机长度为11位,并 ...

  7. Vue初学跳坑

    1. uncaught TypeError: Cannot read property '0' of undefined <div class="home-module-wrap&qu ...

  8. 集群搭建(一)克隆虚拟机静态IP设置

    [抛出问题] 当在搭建集群的时候,我们会将一个安装好相关程序的虚拟机进行克隆,克隆之后,我们会发下一些问题:就是原先的eth0 网卡不见了 原先的网卡 而克隆之后的网卡 会发现原来的网卡eth0 变为 ...

  9. PAT1102: Invert a Binary Tree

    1102. Invert a Binary Tree (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  10. 【线程系列四】[转]监听器-java同步的基本思想

    转自:http://ifeve.com/think-in-java-monitor/ 如果你在大学学习过操作系统,你可能还记得监听器在操作系统中是很重要的概念.同样监听器在java同步机制中也有使用, ...