青少年编程与数学 02-006 前端开发框架VUE 15课题、模板引用

青少年编程与数学 02-006 前端开发框架VUE 15课题、模板引用

课题摘要:本文介绍了Vue中的模板引用(Template Refs),它允许访问DOM元素或子组件实例以进行交互。模板引用通过ref属性创建,并在组件渲染完成后可访问。文章讨论了模板引用的用途,包括DOM操作、子组件访问、焦点管理和媒体播放控制。示例代码展示了如何通过模板引用操作输入框,包括聚焦和获取值。注意事项包括模板引用的渲染时机、条件渲染和列表渲染中的使用限制。文章还介绍了useTemplateRef()方法,用于在组合式API中获取模板引用。最后,提供了一个项目示例,展示了如何使用模板引用操作DOM元素。


一、模板引用

在Vue中,模板引用(Template Refs)是一种特殊的属性(ref),用于给元素或子组件注册引用信息。通过模板引用,你可以访问DOM元素或子组件实例,以便直接与它们进行交互。

以下是模板引用的一些常见用途:

  1. 访问DOM元素:获取DOM元素的引用,以便进行原生DOM操作,如获取元素的尺寸、位置或执行动画。

  2. 访问子组件实例:获取子组件的实例,以便调用其方法或访问其数据。

  3. 焦点管理:控制输入框或其他可聚焦元素的焦点。

  4. 媒体播放控制:控制视频或音频元素的播放。

使用模板引用

在Vue模板中,你可以通过ref属性为元素或子组件添加引用:

html 复制代码
<template>
  <input ref="inputRef" />
  <button @click="focusInput">Focus Input</button>
</template>

<script setup>
import { ref } from 'vue';

const inputRef = ref(null);

function focusInput() {
  inputRef.value.focus();
}
</script>

在这个例子中,inputRef是一个模板引用,它引用了模板中的<input>元素。通过inputRef.value,我们可以直接访问这个DOM元素,并调用其focus方法。

组件中的模板引用

你也可以在组件中使用模板引用来访问子组件实例:

html 复制代码
<template>
  <ChildComponent ref="childRef" />
</template>

<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const childRef = ref(null);

// 调用子组件的方法
function callChildMethod() {
  childRef.value.someMethod();
}
</script>

在这个例子中,childRef引用了ChildComponent的实例,你可以通过childRef.value来访问子组件的属性和方法。

注意事项

  • 模板引用在组件渲染完成后才可访问,即在mounted生命周期钩子之后。
  • 模板引用不会触发组件的重新渲染。
  • 如果元素或子组件被条件渲染(如v-ifv-show)或循环渲染(如v-for),则需要确保在访问引用时它们是存在的。

模板引用提供了一种直接与DOM元素或子组件实例交互的方式,使得你可以执行一些Vue响应式系统之外的操作。

二、使用限制

模板引用(Template Refs)在Vue中是一个非常有用的功能,但它也有一些限制和注意事项:

  1. 渲染时机

    • 模板引用在组件渲染完成后才可用。这意味着你不能在setup函数或生命周期钩子beforeMount中访问它们,因为在这些阶段DOM还未渲染完成。
  2. 条件渲染

    • 如果一个元素被v-if条件渲染,那么在条件为false时,该元素的引用将为null。你需要确保在条件为true时再访问引用。
  3. 列表渲染

    • 当使用v-for时,每个循环项都会有一个模板引用,但你需要通过函数或具名插槽来访问它们,因为它们不是简单地附加到循环项的上下文。
  4. 动态组件和v-if

    • 如果一个组件被包裹在v-if中,或者是一个动态组件,那么它的模板引用可能在组件切换时发生变化,因为旧的组件实例会被销毁,而新的组件实例会被创建。
  5. 响应式

    • 模板引用本身不是响应式的,它们只是对DOM元素或子组件实例的普通引用。如果你需要响应式地监控引用的变化,你需要使用watchwatchEffect来观察ref的变化。
  6. 跨组件通信

    • 模板引用不能直接用于跨组件通信。如果你需要访问另一个组件的内部状态或方法,你应该使用props、emit或provide/inject。
  7. 全局方法

    • Vue没有提供全局方法来访问所有模板引用,你需要在每个组件内部单独声明和管理它们。
  8. 样式和类绑定

    • 模板引用不会影响元素的样式或类绑定,它们只是提供了对DOM元素的直接访问。
  9. 限制性

    • 模板引用主要用于直接操作DOM,这与Vue的声明式渲染原则相违背。因此,应该谨慎使用,并尽可能使用Vue的声明式API来处理。
  10. 代码组织

    • 过度使用模板引用可能会导致代码难以维护,因为它使得组件之间的耦合更加紧密,且容易出错。
  11. SSR限制

    • 在服务器端渲染(SSR)的应用中,模板引用在服务器端不可用,因为服务器端没有DOM。
  12. 类型检查

    • 如果你使用TypeScript,可能需要为模板引用提供额外的类型注解,以确保类型安全。

使用模板引用时,应该遵循Vue的最佳实践,尽可能保持代码的声明性和可维护性。在大多数情况下,Vue的响应式系统和组件通信机制应该足以处理应用的状态和交互,而无需直接操作DOM。

三、访问模板引用

要在组合式 API 中获取引用,我们可以使用辅助函数 useTemplateRef() :(新方法)

vue

vue 复制代码
<script setup>
import { useTemplateRef, onMounted } from 'vue'

// 第一个参数必须与模板中的 ref 值匹配
const input = useTemplateRef('my-input')

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

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

在使用 TypeScript 时,Vue 的 IDE 支持和 vue-tsc 将根据匹配的 ref attribute 所用的元素或组件自动推断 inputRef.value 的类型。
3.5 前的用法

复制代码
复制代码

注意,你只可以在组件挂载后 才能访问模板引用。如果你想在模板中的表达式上访问 input,在初次渲染时会是 null。这是因为在初次渲染前这个元素还不存在呢!

如果你需要侦听一个模板引用 ref 的变化,确保考虑到其值为 null 的情况:

js

javascript 复制代码
watchEffect(() => {
  if (input.value) {
    input.value.focus()
  } else {
    // 此时还未挂载,或此元素已经被卸载(例如通过 v-if 控制)
  }
})

四、v-for 中的模板引用

需要 v3.2.25 及以上版本。

当在 v-for 中使用模板引用时,对应的 ref 中包含的值是一个数组,它将在元素被挂载后包含对应整个列表的所有元素:

vue

vue 复制代码
<script setup>
import { ref, useTemplateRef, onMounted } from 'vue'

const list = ref([
  /* ... */
])

const itemRefs = useTemplateRef('items')

onMounted(() => console.log(itemRefs.value))
</script>

<template>
  <ul>
    <li v-for="item in list" ref="items">
      {{ item }}
    </li>
  </ul>
</template>

应该注意的是,ref 数组并不保证与源数组相同的顺序。

五、应用示例

好的,下面是一个使用Vue 3和Vite创建的项目示例,这个项目将展示如何使用模板引用来操作DOM元素。

步骤 1:创建Vite项目

首先,确保你已经安装了Node.js和npm/yarn。然后,使用以下命令创建一个新的Vite项目:

bash 复制代码
# 使用npm
npm create vite@latest my-template-refs-vue-app -- --template vue

# 或者使用yarn
yarn create vite my-template-refs-vue-app --template vue

进入项目目录:

bash 复制代码
cd my-template-refs-vue-app

步骤 2:安装Vue 3

确保项目使用的是Vue 3:

bash 复制代码
npm install vue@next

步骤 3:创建模板引用组件

src目录下创建一个新文件TemplateRefsComponent.vue

TemplateRefsComponent.vue:

html 复制代码
<template>
  <div>
    <h1>Template Refs Example</h1>
    <!-- 使用ref属性为input元素创建模板引用 -->
    <input ref="inputRef" placeholder="Type something..." />
    <!-- 使用模板引用调用focus方法 -->
    <button @click="focusInput">Focus Input</button>
    <!-- 使用模板引用获取input的值 -->
    <button @click="printInputValue">Print Input Value</button>
    <!-- 显示input的值 -->
    <p>Input Value: {{ inputValue }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';

// 创建一个响应式变量来存储input的值
const inputValue = ref('');

// 创建模板引用,指向input元素
const inputRef = ref(null);

// 定义一个方法,使用模板引用来聚焦input元素
function focusInput() {
  inputRef.value.focus();
}

// 定义一个方法,使用模板引用来获取input的值,并更新inputValue响应式变量
function printInputValue() {
  inputValue.value = inputRef.value.value;
}
</script>

<style scoped>
button {
  margin: 5px;
}
</style>

步骤 4:在App.vue中使用TemplateRefsComponent

编辑src/App.vue文件,引入并使用TemplateRefsComponent

html 复制代码
<template>
  <div id="app">
    <template-refs-component />
  </div>
</template>

<script setup>
import TemplateRefsComponent from './components/TemplateRefsComponent.vue';
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

步骤 5:运行项目

使用以下命令启动开发服务器:

bash 复制代码
npm run dev

# 或者使用yarn
yarn dev

现在,你可以在浏览器中访问http://localhost:3000来查看你的应用。你可以通过点击"Focus Input"按钮来聚焦到输入框,点击"Print Input Value"按钮来打印输入框的值。

项目说明

这个项目包含了一个TemplateRefsComponent.vue组件,它展示了如何使用模板引用来操作DOM元素。在这个组件中:

  • 我们为<input>元素创建了一个模板引用inputRef
  • 我们定义了两个按钮,一个用于聚焦到输入框,另一个用于打印输入框的值。
  • 我们使用模板引用inputRef.value.focus()来聚焦输入框。
  • 我们使用模板引用inputRef.value.value来获取输入框的值,并更新响应式变量inputValue

通过这个项目,你可以了解如何在Vue中使用模板引用来直接操作DOM元素。这是一个基本的示例,你可以根据需要进行扩展和修改。

相关推荐
草木红几秒前
六、Angular 发送请求/ HttpClient 模块
服务器·前端·javascript·angular.js
baozhengw3 分钟前
SpringBoot项目实战(39)--Beetl网页HTML文件中静态图片及CSS、JS文件的引用和展示
javascript·css·html·beetl
kkkkatoq17 分钟前
EasyExcel的应用
java·前端·servlet
阿雄不会写代码25 分钟前
使用java springboot 使用 Redis 作为限流工具
前端·bootstrap·html
answerball26 分钟前
Vue3 开发指南:从零到前端大神的轻松之旅 🚀
前端·vue.js
匹马夕阳32 分钟前
(一)Canvas极简入门
前端·图形渲染
xiangzhihong835 分钟前
在Windows上 安装使用repo
前端·android-studio
!!!5251 小时前
lombok在高版本idea中注解不生效的解决
java·服务器·前端
胡译胡说1 小时前
DOOM游戏风格的验证码——能杀死3个怪物你就不是自动化程序
前端·游戏·设计
xwm10001 小时前
next.js实现SSR入门
前端·javascript·chrome