Skip to content

ref - 模板引用

与原生 JavaScript 和 jQuery 相比较,现代前端框架(Vue、React、Angular 等)很少需要开发者通过 DOM 接口访问和操作元素。但我们偶尔也需要访问元素或组件:

<template>
<h2>ref</h2>
<input
type="text"
name="username"
ref="usernameInput">
</template>
<script>
export default {
name: 'DemoRef',
mounted() {
this.focus();
},
methods: {
focus() {
const {
usernameInput,
} = this.$refs;
if (usernameInput) {
usernameInput.focus();
}
},
},
};
</script>

ref=“refName” 声明引用 ID

ref 属性用于指定引用的 ID,可以应用到 DOM 元素或自定义组件上,以获得 DOM 元素或组件实例的引用:

<input
type="text"
name="username"
ref="usernameInput">
<hello-world
ref="helloworldComponent" />
  • 引用 ID(或引用名称)可以是 refNameref-name 的形式(但建议仅使用 refName 形式,因为这样更方便访问和使用)。
  • 引用 ID 应当是唯一的。
  • 当存在多个同名的引用时,只有最后一个元素会被引用。
<template>
<ul>
<li
v-for="(item, index) in list"
:key="index"
ref="listItems">{{ item }}</li>
</ul>
</template>
<script>
list: [
'A',
'B',
'C',
],
this.$refs.listItems; // => <li>C</li>
</script>

在 Vue 2 中,v-for 中可以重复绑定引用 ID,引用的元素会保存至数组中。

Vue 3 不再支持这种方式,可以使用下面的方式手动处理。

:ref =“func” 手动处理引用

<template>
<ul>
<li
v-for="(item, index) in list"
:key="index"
:ref="refItems">{{ item }}</li>
</ul>
</template>
<script>
export default {
name: 'DemoRef',
data() {
return {
list: [
'A',
'B',
'C',
],
listItems: [],
};
},
mounted() {
console.log(this.listItems);
},
methods: {
refItems(el) {
this.listItems.push(el);
},
},
};
</script>

ref 属性可以绑定一个方法 :ref="refItems"

refItems(el) {
this.listItems.push(el);
},

该方法可以包含一个参数,代表当前的 DOM 元素或组件实例。

利用这种方法的一个例子:

<template>
<input
type="password"
name="password"
:ref="autoHint" />
</template>
<script>
autoHint(el) {
el.setAttribute('placeholder', el.name);
},
</script>

autoHint 方法会自动将 input 元素的 “name” 属性值作为占位文本。

this.$refs - 访问元素/组件

ref="refName" 会在模板完成渲染后,自动绑定元素或组件到 this.$refs.refName

<template>
<input
type="text"
name="username"
ref="usernameInput" />
<hello-world
msg="hello"
ref="helloWorldElement" />
<button
@click="mute">mute</button>
</template>
<script>
focus() {
const {
usernameInput,
} = this.$refs;
if (usernameInput) {
usernameInput.focus();
}
},
mute() {
const {
helloWorldElement,
} = this.$refs;
if (helloWorldElement) {
// 访问自定义组件的属性和方法
console.log(helloWorldElement.msg);
helloWorldElement.mute();
}
},
</script>
hello-world.vue
<template>
<p>{{ muted ? '(muted)' : msg }}</p>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
muted: false,
};
},
props: {
msg: String,
},
methods: {
mute() {
this.muted = true;
},
},
};
</script>