让 Vue 模板引用更加简洁清晰

发布时间:2023年12月22日

本文翻译自 Make Vue’s template refs clean & simple,作者:Roobin S?n, 略有删改。

在Vue项目中有时候我们可能需要直接访问模板中的DOM元素。一个常见的用例是,当我们为组件定义expose(defineExposes)时,父组件需要访问该组件来调用已暴露的函数或属性。

当我第一次使用Vue的template refs时,我感觉有些奇怪。这是一个例子:

<template>
  <input ref="input" />
</template>

setup 脚本:

<script setup>
import { ref, onMounted } from 'vue'

const input = ref(null)

onMounted(() => {
  input.value.focus()
})
</script>

这里有2个问题:

问题1:为什么模板中的inputconst字符串,而设置脚本中的inputref变量?为什么我们不能像:ref="input"那样传递ref变量,而不是总是记住我们需要让脚本中的变量名和模板中的字符串相同?如果你使用Typescript比较多,你会觉得这很奇怪。

问题2:为什么我们需要调用input.value来访问组件?在大多数情况下,这个模板ref通常是不变的,所以调用.value是不必要的。我们不需要它是一个可变的ref变量,我们只希望它是一个常量。

在尝试了一些方法,如使用反应,常量,…我终于为这个问题做了一个实用程序,只有10行代码。

import { reactive } from 'vue'

export const useRefs = <T extends object>() => {
  const refs = reactive<T>({} as T)
  const toRef = (refName: keyof T) => (el: any) => ((refs as T)[refName as keyof T] = el)

  return {
    refs,
    toRef,
  }
}

使用方式:

<template>
  <input :ref="toRef('input')" />
</template>

<script setup lang="ts">
import { onMounted } from 'vue'
import { useRefs } from '@common/utils/useRefs'

const { refs, toRef } = useRefs<{
  input: InstanceType<typeof HTMLInputElement>
}>()

onMounted(() => {
  refs.input.focus()
})
</script>

上述方案有几个有点:

  • 引用名input现在只是一个对象的常量。IDE可以很容易地理解它,所以在IDE中输入的提示就是一个很不错的体验。例如:

  • 不仅是IDE,编译器也工作得更好。它可以验证组件语法问题。例如,当我错误地将函数的名称从focus()输入为focuses()时:

只需要几行代码,Vue的模板引用的问题就变成了零。更少的IDE警告、更少的未知错误和更安全的类型检查。这个解决方案使我在使用模板引用时更加舒适。

希望这对你也有帮助,如果你有更好的解决办法,欢迎留言交流。


看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

文章来源:https://blog.csdn.net/qq_37247349/article/details/135145597
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。