青少年编程与数学 02-006 前端开发框架VUE 15课题、模板引用
- 一、模板引用
- 二、使用限制
- 三、访问模板引用
- [四、`v-for` 中的模板引用](#四、
v-for
中的模板引用) - 五、应用示例
-
-
- [步骤 1:创建Vite项目](#步骤 1:创建Vite项目)
- [步骤 2:安装Vue 3](#步骤 2:安装Vue 3)
- [步骤 3:创建模板引用组件](#步骤 3:创建模板引用组件)
- [步骤 4:在App.vue中使用TemplateRefsComponent](#步骤 4:在App.vue中使用TemplateRefsComponent)
- [步骤 5:运行项目](#步骤 5:运行项目)
- 项目说明
-
课题摘要:本文介绍了Vue中的模板引用(Template Refs),它允许访问DOM元素或子组件实例以进行交互。模板引用通过
ref
属性创建,并在组件渲染完成后可访问。文章讨论了模板引用的用途,包括DOM操作、子组件访问、焦点管理和媒体播放控制。示例代码展示了如何通过模板引用操作输入框,包括聚焦和获取值。注意事项包括模板引用的渲染时机、条件渲染和列表渲染中的使用限制。文章还介绍了useTemplateRef()
方法,用于在组合式API中获取模板引用。最后,提供了一个项目示例,展示了如何使用模板引用操作DOM元素。
一、模板引用
在Vue中,模板引用(Template Refs)是一种特殊的属性(ref
),用于给元素或子组件注册引用信息。通过模板引用,你可以访问DOM元素或子组件实例,以便直接与它们进行交互。
以下是模板引用的一些常见用途:
-
访问DOM元素:获取DOM元素的引用,以便进行原生DOM操作,如获取元素的尺寸、位置或执行动画。
-
访问子组件实例:获取子组件的实例,以便调用其方法或访问其数据。
-
焦点管理:控制输入框或其他可聚焦元素的焦点。
-
媒体播放控制:控制视频或音频元素的播放。
使用模板引用
在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-if
、v-show
)或循环渲染(如v-for
),则需要确保在访问引用时它们是存在的。
模板引用提供了一种直接与DOM元素或子组件实例交互的方式,使得你可以执行一些Vue响应式系统之外的操作。
二、使用限制
模板引用(Template Refs)在Vue中是一个非常有用的功能,但它也有一些限制和注意事项:
-
渲染时机:
- 模板引用在组件渲染完成后才可用。这意味着你不能在
setup
函数或生命周期钩子beforeMount
中访问它们,因为在这些阶段DOM还未渲染完成。
- 模板引用在组件渲染完成后才可用。这意味着你不能在
-
条件渲染:
- 如果一个元素被
v-if
条件渲染,那么在条件为false
时,该元素的引用将为null
。你需要确保在条件为true
时再访问引用。
- 如果一个元素被
-
列表渲染:
- 当使用
v-for
时,每个循环项都会有一个模板引用,但你需要通过函数或具名插槽来访问它们,因为它们不是简单地附加到循环项的上下文。
- 当使用
-
动态组件和
v-if
:- 如果一个组件被包裹在
v-if
中,或者是一个动态组件,那么它的模板引用可能在组件切换时发生变化,因为旧的组件实例会被销毁,而新的组件实例会被创建。
- 如果一个组件被包裹在
-
响应式:
- 模板引用本身不是响应式的,它们只是对DOM元素或子组件实例的普通引用。如果你需要响应式地监控引用的变化,你需要使用
watch
或watchEffect
来观察ref
的变化。
- 模板引用本身不是响应式的,它们只是对DOM元素或子组件实例的普通引用。如果你需要响应式地监控引用的变化,你需要使用
-
跨组件通信:
- 模板引用不能直接用于跨组件通信。如果你需要访问另一个组件的内部状态或方法,你应该使用props、emit或provide/inject。
-
全局方法:
- Vue没有提供全局方法来访问所有模板引用,你需要在每个组件内部单独声明和管理它们。
-
样式和类绑定:
- 模板引用不会影响元素的样式或类绑定,它们只是提供了对DOM元素的直接访问。
-
限制性:
- 模板引用主要用于直接操作DOM,这与Vue的声明式渲染原则相违背。因此,应该谨慎使用,并尽可能使用Vue的声明式API来处理。
-
代码组织:
- 过度使用模板引用可能会导致代码难以维护,因为它使得组件之间的耦合更加紧密,且容易出错。
-
SSR限制:
- 在服务器端渲染(SSR)的应用中,模板引用在服务器端不可用,因为服务器端没有DOM。
-
类型检查:
- 如果你使用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元素。这是一个基本的示例,你可以根据需要进行扩展和修改。