Vue3 中 ref 与模板引用(template refs)的深入剖析与迁移策略
笔记哥 /
05-09 /
11点赞 /
0评论 /
282阅读
# Vue 3中的ref和template refs详解
在Vue 3中,`ref`和模板引用(template refs)是两个相关但不同的概念,它们在组合式API(Composition API)中扮演着重要角色。
## ref - 响应式引用
`ref`是Vue 3中创建响应式数据的主要方式之一。
### 基本用法
```typescript
import { ref } from 'vue'
// 创建一个响应式引用
const count = ref(0)
// 访问或修改值需要使用.value
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
```
### 特点
1. **包装原始值**:`ref`可以将基本类型(如数字、字符串、布尔值)转换为响应式对象
2. **需要使用.value**:在JavaScript中访问或修改ref值时,必须使用`.value`属性
3. **在模板中自动解包**:在模板中使用时,Vue会自动解包ref,不需要写`.value`
```vue
```
### Vue 3中的使用方式
在Vue 3的组合式API中,模板引用的使用方式发生了变化:
1. **创建ref变量**:首先创建一个ref变量
2. **在模板中绑定**:将这个ref变量绑定到元素或组件上
3. **在组件挂载后访问**:组件挂载后,ref变量的`.value`将包含对应的DOM元素或组件实例
```vue
```
### 动态模板引用(v-for中使用)
在循环中使用模板引用时,需要使用函数形式的ref:
```vue
```
## 示例:关于v-for生成的ref的复杂例子,Vue2+js移植到Vue3+TS
>
>
> 旧的Vue2+js程序:
>
>
>
> ```vue
>
> :ref="`col-${index}`" :x="0" :y="0" :parent="item" :deviceIp="deviceIp" :modelName="modelName"
> :paramName="paramName" :index="index" :channel="this.colPageIndex * this.pageColCount + index"
> :ctrlItemType="'mixer-input'" />
> :ref="`row-${index}`" :parent="item" :deviceIp="deviceIp" :modelName="modelName" :paramName="paramName"
> :index="index" :channel="this.rowPageIndex * this.pageRowCount + index" :ctrlItemType="'mixer-output'" />
>
> :ref="`row-${rowIndex}-col-${colIndex}`" :x="0" :y="0" :parent="item" :deviceIp="deviceIp"
> :modelName="modelName" :paramName="paramName" :rowIndex="rowIndex" :colIndex="colIndex"
> :channel="this.rowPageIndex * this.pageRowCount + rowIndex"
> :extraData2="this.colPageIndex * this.pageColCount + colIndex" :ctrlItemType="'mixer-node'" />
>
>
> ```
>
>
>
> ```javascript
> // 使用到ref的位置示例,type获取细节不表
> const refMap = {
> 'in-gain': `col-${channel}`,
> 'out-gain': `row-${channel}`,
> 'node-gain': `row-${channel}-col-${nodeInputChannel}`,
> 'in-btn': `col-${channel}`,
> 'out-btn': `row-${channel}`,
> 'node-btn': `row-${channel}-col-${nodeInputChannel}`,
> };
>
> const refName = refMap[type];
> if (!refName) {
> console.error('Unknown type:', type);
> return null;
> }
>
> // 处理数组型 ref(v-for 产生的)
> const refs = this.$refs[refName];
> ```
>
在示例中,需要从Vue 2风格的`$refs`迁移到Vue 3的模板引用方式。具体步骤:
1. 定义模板引用数组:
```typescript
const inputGainRefs = ref([])
const outputGainRefs = ref([])
const nodeGainRefsMap = ref([])
```
1. 在模板中使用这些引用:
```vue
```
1. 在需要访问子组件时:
```typescript
// 访问输入增益组件
inputGainRefs.value[0].someMethod()
// 访问节点增益组件
nodeGainRefsMap.value[rowIndex][colIndex].someMethod()
```
## 总结
1. **ref**:用于创建响应式数据,在JavaScript中需要使用`.value`访问
2. **template refs**:用于访问DOM元素或组件实例
- 在Vue 2中通过`this.$refs`访问
- 在Vue 3中通过创建ref变量并在模板中绑定来实现
3. **迁移策略**:
- 创建对应的ref变量
- 在模板中使用`:ref`绑定
- 在组件挂载后通过`.value`访问实际元素或组件
这种方式不仅符合Vue 3的组合式API设计理念,还提供了更好的类型推断支持,特别是在使用TypeScript的项目中。
{{ count }}
```
### 复杂数据结构
对于对象和数组,`ref`内部使用`reactive`来实现响应式:
```typescript
const user = ref({
name: '张三',
age: 30
})
// 修改属性
user.value.age = 31
```
## template refs - 模板引用
模板引用允许你直接访问DOM元素或组件实例。
### Vue 2中的使用方式
在Vue 2中,我们通过`this.$refs`访问模板引用:
```vue
- {{ item }}
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/3197
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利