vue中$refs的三种用法

我们都知道,在vue2中获取DOM元素,可以直接在元素上绑定ref属性,然后获取到DOM元素的属性值,这种方法在vue3 中仍然可以使用,但也会有一些问题。下面就介绍$refs的三种用法:

1、vue2中

在vue2中,我们可以直接使用ref获取元素,也就是直接在元素上绑定ref属性,在直接使用this.$refs[‘自定义属性名’] 就能直接获取。但是这样也是有一定风险的。因为ref绑定的在元素上,所以当元素没有进行渲染时,是不能通过ref获取到元素的。

<template>
  <div>
    <div ref="btn">我是一个按钮</div>
  </div>
</template>

<script>

export default {
  name: 'App',
  created() {
    //直接使用this.$refs获取DOM元素
    console.log(this.$refs.btn); // undefined
    this.$nextTick(() => {
		console.log(this.$refs.btn)  //获取到正确元素
	})
  },
  mounted() {
	console.log(this.$refs.btn); //获取到正确元素
  }
}
</script>

需要注意的是,在于vue2中使用这种方法获取v-for的元素时,获取到的是一个数组

<template>
  <div>
    <div ref="btn" v-for="(item , index) in 3" :key="index">我是一个按钮</div>
  </div>
</template>

<script>

export default {
  name: 'App',
  mounted() {
    //获取到的是一个元素数组 
	console.log(this.$refs.btn); 
  }
}
</script>

2、vue3中

在一般情况下,vue2的获取元素的方法在vue3也完全适用。

但是,有时候可能会遇到无法获取这个节点,原因是生命周期的问题,在vue3中原来的created没有了,而 setup 充当了原来的 created。所以在 setup 的时候,dom元素还没有被创建,只有setup完毕了之后HTML才能构建,这时才能真正访问到value值,所以自然就无法获取到dom节点,要想解决这个问题,就要配合钩子函数 onMounted ,在dom挂载完毕后再进行获取。

<template>
	<div id="ref">
        <!--在元素上用 ref="butRef" 绑定-->
		<button type="button" ref="butRef" >按钮元素</button>
	</div>
</template>

<script>
    //引入ref
	import {ref, onMounted} from 'vue'
	export default {
		setup() {

            //需要先定义butRef
			let butRef = ref(null)
            onMounted(()=>{
              //使用的时候为 butRef.value(需要加点value获取DOM元素值)
			  console.log(butRef.value);
            })
			return {
				butRef
			}
		}
	}
</script>

3、vue3的组合API(composition-api)

最后一种方法就是从上下文 Ctx(context)中解构构出 refs,虽然这里refs可能会提示已经被弃用,但是在这里仍然是可以用的。

<template>
	<div id="ref">
		<button type="button" ref="butRef" >按钮元素</button>
	</div>
</template>

<script lang="ts">
import { defineComponent, ref, watch } from '@vue/composition-api';

export default defineComponent({
    name: '',
    components: {},
    setup (props, ctx) {
        //从Ctx(context)中解构出 refs
        const { emit, refs } = ctx;
            
        watch(filterText, (val) => {
            //在使用的时候直接用 refs.butRef
            //refs.butRef.filter(val);
            (refs.butRef as Any).filter(val);
        });
		return {
			butRef
		}
	}
}
</script>

<think>好的,我需要回答用户关于Vue2Vue3中$refs用法的比较及实现差异的问题。首先,我需要回顾Vue2中的$refs使用方式。在Vue2中,$refs用于直接访问子组件或DOM元素,通常在模板中使用ref属性,然后在JavaScript中通过this.$refs访问。例如: 在模板中: ```html <div ref="myDiv">Hello</div> ``` 在JavaScript中: ```javascript this.$refs.myDiv.innerHTML = 'Updated'; ``` 接下来是Vue3。Vue3引入了Composition API,并且对响应式系统进行了重构,使用Proxy代替了Object.defineProperty。这会影响$refs的实现。在Vue3中,虽然仍然可以使用类似的ref属性,但在Composition API中,通常会使用ref函数来创建响应式变量。例如: 在模板中: ```html <div ref="myDiv">Hello</div> ``` 在脚本中使用Composition API: ```javascript import { ref, onMounted } from 'vue'; setup() { const myDiv = ref(null); onMounted(() => { myDiv.value.innerHTML = 'Updated'; }); return { myDiv }; } ``` 这里需要注意的是,Vue3中的ref在模板中会自动解包,所以不需要.value,但在JavaScript中需要通过.value访问。另外,Vue3的$refs在选项式API中的用法Vue2类似,但可能有一些变化,比如在组合式API中的处理方式不同。 然后需要比较两者的差异。实现机制上,Vue2使用Object.defineProperty进行响应式跟踪,而Vue3使用Proxy,这使得Vue3的响应式系统更高效,并能检测更多变化类型。在组合式API中,Vue3的ref函数返回的是一个响应式对象,访问时需要.value,但在模板中自动解包。而Vue2$refs是直接访问DOM或组件实例,没有响应式包装。 另外,Vue3中的$refs可能在某些情况下被废弃或改变,比如在组合式API中更推荐使用ref函数和模板引用的方式。同时,Vue3支持多个根元素,因此在多根组件中使用ref时可能需要更注意。 还要考虑用户可能遇到的常见问题,比如在Vue3中何时使用ref函数,何时使用$refs,以及响应式处理的差异。此外,性能优化方面,Vue3的Proxy实现可能更高效,尤其是在处理大型应用时。 需要确保回答结构清晰,分点说明用法、实现差异、注意事项,并给出示例代码。同时,根据用户提供的参考引用,可能涉及不可变对象的使用,但当前问题主要围绕$refs,所以可能不需要深入这部分,除非有关联。 最后,生成相关问题,比如Vue3中响应式系统的原理,组合式API的优势,或者如何迁移Vue2$refsVue3等。</think>### Vue2Vue3中$refs用法及实现差异 #### 1. **Vue2中的$refs用法** 在Vue2中,`$refs`用于直接访问子组件实例或DOM元素。通过模板中的`ref`属性标记目标元素或组件,然后在JavaScript中通过`this.$refs`访问。 **示例**: ```html <template> <div> <child-component ref="child"></child-component> <button ref="submitBtn">Submit</button> </div> </template> <script> export default { mounted() { this.$refs.child.method(); // 调用子组件方法 this.$refs.submitBtn.click(); // 操作DOM } } </script> ``` #### 2. **Vue3中的$refs用法** Vue3保留了`ref`属性的基本功能,但结合Composition API时更推荐使用`ref`函数创建响应式引用。 **示例(选项式API)**: ```html <template> <div> <child-component ref="child"></child-component> <button ref="submitBtn">Submit</button> </div> </template> <script> export default { mounted() { this.$refs.child.method(); this.$refs.submitBtn.click(); } } </script> ``` **示例(组合式API)**: ```html <template> <div ref="rootElement"> <button @click="logRef">Log Ref</button> </div> </template> <script> import { ref, onMounted } from 'vue'; export default { setup() { const rootElement = ref(null); onMounted(() => { console.log(rootElement.value); // 访问DOM元素 }); return { rootElement }; } } </script> ``` #### 3. **核心差异** | 特性 | Vue2 | Vue3 | |---------------------|-------------------------------|-------------------------------| | **响应式实现** | 基于`Object.defineProperty` | 基于`Proxy`,支持深层响应式[^1] | | **组合式API支持** | 无 | 通过`ref()`函数创建响应式引用 | | **模板引用解包** | 直接通过`this.$refs`访问 | 在模板中自动解包,脚本中需`.value` | | **多根组件支持** | 不支持 | 支持多根组件,需显式指定`ref`目标 | #### 4. **注意事项** - **响应式更新**:Vue3的`ref`函数返回的是响应式对象,修改其值会触发视图更新;Vue2的`$refs`仅用于直接访问,无响应式绑定。 - **性能优化**:Vue3的`Proxy`实现减少了初始化时的递归遍历,提升大型应用性能。 - **TypeScript支持**:Vue3对`ref`的类型推断更完善,尤其在组合式API中。 #### 5. **迁移建议** - 将Vue2的`this.$refs.xxx`替换为组合式API的`const xxx = ref(null)`。 - 在脚本中操作引用时,Vue3需通过`xxx.value`访问(模板中无需)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值