Vue的ref的使用
【摘要】 Vue的ref的使用问题:动态操作 DOM 元素假设你正在开发一个简单的页面,页面上有多个标题元素(h1、h2、h3),你希望通过按钮点击动态输出这些标题元素的内容。具体需求如下:页面上有三个标题元素:h1 显示“中国”h2 显示“贵州”h3 显示“贵阳”页面上有两个按钮:点击第一个按钮时,输出 h2 元素的内容。点击第二个按钮时,输出 h3 元素的内容。问题描述如何通过按钮点击动态获取并输...
Vue的ref的使用
问题:动态操作 DOM 元素
假设你正在开发一个简单的页面,页面上有多个标题元素(h1
、h2
、h3
),你希望通过按钮点击动态输出这些标题元素的内容。具体需求如下:
- 页面上有三个标题元素:
-
h1
显示“中国” -
h2
显示“贵州” -
h3
显示“贵阳”
- 页面上有两个按钮:
-
点击第一个按钮时,输出
h2
元素的内容。 -
点击第二个按钮时,输出
h3
元素的内容。
问题描述
-
如何通过按钮点击动态获取并输出
h2
和h3
的内容? -
如何避免使用传统的
id
或class
来操作 DOM 元素,而是使用 Vue 3 提供的ref
属性?
如果是id与其他页面的id重复了怎么办?
实现思路
这时候就需要ref了,id
:在整个 HTML 文档中必须是唯一的,否则会导致冲突。而ref
:在 Vue 组件的作用域内是唯一的,不会与其他组件冲突。
- 使用
ref
绑定 DOM 元素:
-
在
h2
和h3
上分别绑定ref
,给它们打上标记。 -
在按钮的点击事件中,通过
ref
获取对应的 DOM 元素并输出其内容。
- 组件化开发:
- 如果这些标题和按钮是一个组件的一部分,如何在父组件中访问子组件的内容?
代码实现
HTML 结构
HTML复制
<template>
<div>
<h1>中国</h1>
<h2 ref="title2">贵州</h2>
<h3 ref="title3">贵阳</h3>
<button @click="showTitle2">点我输出 h2 元素</button>
<button @click="showTitle3">点我输出 h3 元素</button>
</div>
</template>
脚本逻辑
JavaScript复制
<script setup lang="ts">
import { ref } from 'vue';
const title2 = ref(null); // 用于存储 h2 元素的引用
const title3 = ref(null); // 用于存储 h3 元素的引用
const showTitle2 = () => {
console.log(title2.value.textContent); // 输出 h2 的内容
};
const showTitle3 = () => {
console.log(title3.value.textContent); // 输出 h3 的内容
};
</script>
运行效果
-
点击“点我输出 h2 元素”按钮时,控制台会输出“贵州”。
-
点击“点我输出 h3 元素”按钮时,控制台会输出“贵阳”。
详细讲解 ref
的用法和原理
一、ref
的基本用法
(一)绑定到普通 HTML 元素
ref
可以绑定到普通 HTML 元素上,例如 <div>
、<h1>
、<button>
等。通过 ref
,你可以轻松地获取这些元素的引用。
HTML复制
<h2 ref="title2">北京</h2>
(二)访问 DOM 元素
在 setup
函数中,通过 ref
获取 DOM 元素的引用,并通过 .value
访问它。
JavaScript复制
const title2 = ref(null);
const showTitle2 = () => {
console.log(title2.value.textContent); // 输出 h2 的内容
};
二、ref
用于组件实例
(一)绑定到组件实例
ref
也可以绑定到组件实例上。通过 ref
,你可以获取组件实例的引用,并访问其方法和数据。
HTML复制
<Person ref="person" />
(二)访问组件实例
在 setup
函数中,通过 ref
获取组件实例的引用,并通过 .value
访问它。
JavaScript复制
const person = ref(null);
const showPerson = () => {
console.log(person.value); // 输出 Person 组件实例
};
三、ref
的原理
(一)依赖收集
-
当
ref
被绑定到 DOM 元素或组件实例时,Vue 会自动将这些元素或实例收集为依赖项。 -
在组件挂载时,Vue 会将这些依赖项存储在
ref
的value
属性中。
(二)访问依赖
-
通过
ref.value
,你可以访问绑定的 DOM 元素或组件实例。 -
如果绑定的是组件实例,你可以通过
ref.value
访问组件的methods
、data
等属性。
(三)组件实例的保护
-
Vue 3 对组件实例的访问进行了保护,防止父组件直接访问子组件的内部状态。
-
如果需要让父组件访问子组件的某些属性或方法,需要在子组件中使用
defineExpose
显式暴露。
子组件:使用 defineExpose
显式暴露需要被父组件访问的属性和方法。
父组件:通过 ref
绑定子组件实例,并访问子组件暴露的内容。
在 Vue 3 中,组件实例的保护机制是一个重要的特性,它防止父组件直接访问子组件的内部状态,从而确保组件的封装性和数据的安全性。如果需要让父组件访问子组件的某些属性或方法,必须在子组件中显式暴露这些内容。接下来,我们将通过一个实际例子来展示组件实例保护的机制。
组件实例保护的示例
1. 子组件 Person.vue
假设我们有一个子组件 Person.vue
,它包含一些内部数据和方法。我们希望父组件能够访问其中的一部分数据和方法,但不是全部。
子组件代码
HTML复制
<template>
<div>
<h4>姓名:{{ name }}</h4>
<h4>年龄:{{ age }}</h4>
<button @click="sayHello">打招呼</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { defineExpose } from 'vue';
const name = ref('张三');
const age = ref(18);
const sayHello = () => {
console.log(`你好,我叫${name.value},今年${age.value}岁了`);
};
// 显式暴露部分数据和方法
defineExpose({
name, // 暴露姓名
sayHello // 暴露打招呼的方法
});
</script>
2. 父组件
在父组件中,我们通过 ref
绑定子组件实例,并尝试访问子组件的属性和方法。
父组件代码
HTML复制
<template>
<div>
<Person ref="person" />
<button @click="showName">显示姓名</button>
<button @click="callSayHello">调用打招呼方法</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Person from './Person.vue';
const person = ref(null);
const showName = () => {
console.log(person.value.name); // 访问子组件暴露的姓名
};
const callSayHello = () => {
person.value.sayHello(); // 调用子组件暴露的方法
};
</script>
3. 运行效果
-
点击“显示姓名”按钮:
-
控制台会输出子组件的
name
属性值,例如:“张三”。 -
点击“调用打招呼方法”按钮:
-
控制台会输出子组件的
sayHello
方法的执行结果,例如:“你好,我叫张三,今年18岁了”
组件实例保护的作用体现了封装性和数据安全性,保护子组件的内部数据,防止被外部组件意外修改。
四、最佳实践
(一)普通 HTML 元素
- 直接绑定
ref
,访问ref.value
。
HTML复制
<h2 ref="title2">北京</h2>
JavaScript复制
const title2 = ref(null);
const showTitle2 = () => {
console.log(title2.value.textContent); // 输出 h2 的内容
};
(二)组件实例
- 使用
defineExpose
显式暴露需要访问的属性和方法。
HTML复制
<Person ref="person" />
JavaScript复制
const person = ref(null);
const showPerson = () => {
console.log(person.value); // 输出 Person 组件实例
};
五、总结
也就是说,如果你需要在 Vue 组件中动态操作 DOM 元素或组件实例,建议使用 ref
。如果你需要在普通 HTML 中操作 DOM 元素,可以使用 id
。
通过上述问题和代码实现,你可以看到 ref
在动态操作 DOM 元素和组件实例时的简洁性和高效性。ref
自动追踪依赖项,无需显式指定,非常适合动态响应数据变化的场景。在实际开发中,你可以根据具体需求选择使用 ref
,以实现更高效的数据监听和副作用管理。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)