While the example we looked at – focusing an input
– is one of the most common use cases for Vue template Refs, there are endless possibilities where this feature can be useful for your project.
虽然我们看到的例子–关注一个输入–是Vue模板Refs最常见的用例之一,但这个功能对你的项目有无穷的可能性。
Here are some examples:
-
Animating an element using Javascript
-
Easily changing the inner text or HTML of an element
-
Passing a reference to an element as a prop
-
使用Javascript对元素进行动画处理
-
轻松地改变一个元素的内部文本或HTML
-
将一个元素的引用作为一个道具传递出去
The $refs property in Vue is used to reference DOM elements in the Vue instance’s templates.
Vue中的$refs属性被用来引用Vue实例模板中的DOM元素。
A common use case for $refs is focusing on a DOM element when a certain event happens. The autofocus property works on page loads. But what if you want to give focus back to the username input if login failed?
$refs的一个常见用例是当某个事件发生时聚焦于一个DOM元素。自动聚焦属性在页面加载时起作用。但如果你想在登录失败时把焦点放回用户名的输入上呢?
If you give the username input a ref attribute in your template, you can then access the username input using this.$refs.username as shown below. You can then call the built-in Element#focus() function to give focus to the username input.
如果你在模板中给用户名输入一个ref属性,你就可以用this.$refs.username访问用户名输入,如下图所示。然后你可以调用内置的Element#focus()函数,将焦点转移到用户名输入。
const app = new Vue({
data: () => ({ username: '', password: '', failed: false }),
methods: {
login: async function() {
// Simulate that login always fails, // 模拟登录总是失败
this.failed = true;
// Give focus back to `username` input. If you change the
// 'ref' attribute in the template to 'usernameRef', you
// would do `this.$refs.usernameRef` here.
// 把焦点放回`用户名'的输入。如果你把模板中的'ref'属性改为'usernameRef',你会在这里`this.$refs.usernameRef`。
this.$refs.username.focus();
}
},
template: `
<div>
<input type="text" v-model="username" ref="username" id="username">
<input type="password" v-model="password">
<button v-on:click="login()">Login</button>
<div v-if="failed" id="failed">
Login Failed!
</div>
</div>
`
});
复制代码
With v-for
When you use ref with the v-for directive, Vue gives you a native JavaScript array of elements, not just a single element.
当你使用ref和v-for指令时,Vue会给你一个原生的JavaScript元素数组,
而不仅仅是单个元素。
For example, suppose you have a list of <input>
tags, and you want users to be able to navigate between inputs using the up and down arrow keys. You can access the individual <input>
elements using $refs and call focus() whenever the user presses up or down:
例如,假设您有一个< input>标记列表,并且您希望用户能够使用向上和向下箭头键在输入之间导航。 您可以使用$ refs访问各个< input>元素,并在用户按下向上或向下键时调用 focus ():
const app = new Vue({
data: () => ({ cells: ['foo', 'bar', 'baz'].map(val => ({ val })) }),
mounted: function() {
let cur = 0;
this.$refs.inputs[0].focus();
document.addEventListener('keyup', ev => {
console.log('Got event', ev)
cur = this.$refs.inputs.findIndex(el => document.activeElement === el);
if (cur === -1) {
cur = 0;
}
const numEls = this.cells.length;
if (ev.keyCode === 38) { // Up arrow
cur = (numEls + cur - 1) % numEls;
this.$refs.inputs[cur].focus();
} else if (ev.keyCode === 40) { // Down arrow
cur = (cur + 1) % numEls;
this.$refs.inputs[cur].focus();
}
});
},
template: `
<div>
<div v-for="cell in cells">
<input v-model="cell.val" ref="inputs">
</div>
</div>
`
});
复制代码
一般来讲,获取DOM元素,需要使用document.querySelector(‘#input1’)方法去获取dom节点,然后再获取input1的值。
但是使用了ref绑定之后,我们就不需要再获取dom节点了,可以直接在上面的input上绑定input1,然后$refs里面调用就行。
在JavaScript里面通过this.$refs.input1去调用,这样的做法实际上是访问VUE虚拟出来的DOM,可以有效减少获取/操作DOM节点的性能消耗。