REF的使用

ref 可以用来在 vue 组件实例中获取原生DOM,也可以获取 vue 组件。

获取原生 DOM

步骤

  • 创建 ref: const hRef = ref(null)
  • 模板中和原生 DOM 建立关联: <h1 ref="hRef">我是标题</h1>
  • 使用: hRef.value.原生DOM属性

<script setup>
// 引入 watch
import { ref } from "vue";

const count = ref(0)

// 定义原生DOM容器
const hRef = ref(null)
// 获取原生DOM
const getH1 = () => {
  console.log(hRef.value)
}

// 定义原生DOM容器
const inputRef = ref(null)
// 获取原生DOM
const setFocus = () => {
  inputRef.value.focus()
}

</script>

<template>
  <div>
    <!-- 关联原生DOM -->
    <h1 ref="hRef">{{count}}</h1>
    <button @click="count++">count++</button>
    <input ref="inputRef" type="text" />
    <hr/>
    <button @click="getH1">获取h1</button>
    <button @click="setFocus">设置焦点</button>
  </div>
</template>

 

总结

获取原生 DOM 的场景,当我们无法通过某一个属性控制一些组件时,原因是我们无法定义一个响应式数据和这个状态关联。此时我们可以通过获取原生 DOM 来完成产品需求。

获取自定义组件实例

步骤和获取原生 DOM 相似,不同点是自定义组件要显示定义要暴露的方法和属性。

步骤

  • 创建 ref: const testRef = ref(null)
  • 模板中和原生自定义组件建立关联: <Test ref="testRef" />
  • 自定义组件中使用 defineExpose 函数暴露对外的属性
  • 使用: testRef.value.自定义组件暴露的属性

  • 自定义组件

 

<script setup>

import { ref } from "vue";

// 自定义组件的数据
const testData = ref(0)

// 自定义组件的函数
const testFn = () => {
  console.log(testData.value>3? '大于3': '小于等于3')
}

// 通过 defineExpose 对外暴露属性
defineExpose({testData, testFn})
</script>

<template>
    <div>我是一个自定义组件{{testData}}</div>
    <button @click="testData++">+1</button>
</template>

 父组件中获取自定义组件

 

<script setup>
// 引入 watch
import { ref } from "vue";
import Test2 from "./components/Test2.vue";

const count = ref(0)

// 定义原生DOM容器
const hRef = ref(null)
// 获取原生DOM
const getH1 = () => {
  console.log(hRef.value)
}
// 定义原生DOM容器
const inputRef = ref(null)
// 获取原生DOM
const setFocus = () => {
  inputRef.value.focus()
}

// 定义自定义组件容器
const testRef = ref(null)
// 获取自定义组件
const getTest = () => {
  console.log(testRef.value.testData)
  testRef.value.testFn()
}

</script>

<template>
  <div>
    <!-- 关联原生DOM -->
    <h1 ref="hRef">{{count}}</h1>
    <button @click="count++">count++</button>
    <input ref="inputRef" type="text" />
    <hr/>
    <button @click="getH1">获取h1</button>
    <button @click="setFocus">设置焦点</button>
    <hr/>
    <!-- 关联自定义组件 -->
    <Test2 ref="testRef" />
    <button @click="getTest">获取自定义组件</button>
  </div>
</template>

 

总结

defineExpose 不需要导入可以直接使用

要想自定义组件中的属性对外暴露一定要在 defineExpose 中声明

### 三级标题:React Ref使用方法及最佳实践 在 React 开发中,`ref` 是一个用于访问 DOM 元素或组件实例的引用机制。它在处理焦点控制、文本选择、媒体播放以及与非 React 库交互时非常有用。React 提供了多种方式来创建 `ref`,包括 `React.createRef()`、回调函数形式的 `ref` 以及 `useRef` Hook(在函数组件中使用)[^2]。 #### 创建 Ref 的方式 1. **使用 `React.createRef()`** 在类组件中,可以通过 `React.createRef()` 创建一个 `ref` 并将其附加到 DOM 元素上: ```jsx class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } componentDidMount() { this.myRef.current.focus(); // 设置焦点 } render() { return <input ref={this.myRef} />; } } ``` 2. **使用回调函数形式的 `ref`** 回调函数形式的 `ref` 适用于类组件和函数组件,可以在元素挂载和卸载时执行自定义逻辑: ```jsx class MyComponent extends React.Component { myRef = null; setRef = (element) => { this.myRef = element; }; componentDidMount() { if (this.myRef) { this.myRef.focus(); } } render() { return <input ref={this.setRef} />; } } ``` 3. **使用 `useRef` Hook** 在函数组件中,可以使用 `useRef` Hook 来创建 `ref`,并访问 DOM 元素或保存可变状态: ```jsx import React, { useRef, useEffect } from 'react'; function MyComponent() { const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); // 组件挂载后设置焦点 }, []); return <input ref={inputRef} />; } ``` #### Ref 转发(Forward Ref) 在某些情况下,需要将 `ref` 从父组件传递到子组件内部的 DOM 元素。React 提供了 `React.forwardRef` API 来实现这一功能。通过 `forwardRef`,可以将 `ref` 直接传递给子组件中的某个 DOM 元素或组件实例: ```jsx const Input = React.forwardRef((props, ref) => ( <input ref={ref} {...props} /> )); class ParentComponent extends React.Component { constructor(props) { super(props); this.inputRef = React.createRef(); } componentDidMount() { this.inputRef.current.focus(); // 直接操作子组件中的 input 元素 } render() { return <Input ref={this.inputRef} />; } } ``` #### 使用 Ref 的最佳实践 尽管 `ref` 提供了直接操作 DOM 的能力,但在使用时应遵循以下最佳实践以避免潜在问题: - **避免过度使用 `ref`**:React 推崇声明式编程模型,大多数交互逻辑应通过状态和 props 实现。只有在确实需要直接访问 DOM 或组件实例时才应使用 `ref` [^3]。 - **不要在函数组件中直接使用 `ref`**:函数组件没有实例,因此不能使用 `ref` 直接引用。如果需要引用函数组件内部的 DOM 元素,应使用 `React.forwardRef` [^5]。 - **使用 `useRef` 保存可变状态**:在函数组件中,`useRef` 不仅可用于引用 DOM 元素,还可用于保存可变状态,而不会触发组件重新渲染 。 - **注意生命周期管理**:在 `useEffect` 或 `componentDidMount` 中操作 `ref` 时,应确保 DOM 元素已正确挂载;在 `useEffect` 返回的函数中清理 `ref` 引用,避免内存泄漏 [^4]。 #### 性能与可维护性 合理使用 `ref` 可以提升组件的交互体验,但滥用 `ref` 可能导致组件难以维护和测试。在开发过程中,应结合调试工具(如 React DevTools)检查 `ref` 的使用情况,并确保代码的可测试性和可维护性。此外,在使用第三方库时,应查阅其文档以了解如何正确使用 `ref` 和 `forwardRef`,避免因错误引用导致的运行时异常 [^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值