You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js中如何通过$refs修改<span>元素的文本内容?

Vue中通过$refs修改v-for生成的文本无效问题解决

问题场景

在Vue的<template>中定义了如下<span>元素:

<span ref="span-1">my text</span>

尝试在<script>中通过$refs将其内容从my text修改为my new text,测试了以下写法(搭配innerHTML、innerText、text等属性)均未生效:

this.$refs["span-" + 1].span.value = "my new text";
this.$refs["span-" + 1].value = "my new text";

使用.span时会触发错误:

Uncaught TypeError: Cannot set properties of undefined (setting 'value')

不使用.span时,仅会给$refs对象新增属性,但<span>的实际文本内容无变化。

实际业务代码

表格模板

<table class="table">
    <thead>
        <tr>
            <th 
                 v-for="(column, index) in columns"
                 :key="index"
                 @click="sortRecords(index)"
            > 
                {{column}} <span :ref="'span-' + index"></span>
            </th>
        </tr>                        
    </thead>
    <tbody>
       <tr
           v-for="(row, index) in rows"
           :key="index"
       >
            <td
                  v-for="(rowItem, itemIndex) in row"
                  :key="itemIndex"
            >
                 {{rowItem}} 
            </td>
       </tr>                       
    </tbody>
</table>

排序函数

sortRecords (index) {
     console.log(this.$refs);
     if(this.sortIndex === index){
        switch(this.sortDirection){
            case null:
                 this.sortDirection = 'asc';
                 this.$refs["span-" + index].textContent = "my new text";
                 break;
            case 'asc':
                 this.sortDirection = 'desc';
                 this.$refs["span-" + index].textContent = "my new text";
                 break;
            case 'desc':
                 this.sortDirection = null;
                 this.$refs["span-" + index].textContent = "my new text";
                 break;
         }
    }
} 

关键差异点

测试非v-for生成的<span>时,使用.textContent可正常修改文本;对比发现:

  • 非循环生成的元素,$refs中对应的是单个DOM对象
  • v-for循环生成的元素,$refs中对应的是DOM对象数组

解决方法

方法1:修正$refs取值方式(直接操作DOM)

因为v-for生成的元素在$refs中是数组,需先取数组中的目标元素再修改内容:

sortRecords (index) {
     console.log(this.$refs);
     if(this.sortIndex === index){
        // 取出v-for生成的span数组中的第一个元素
        const targetSpan = this.$refs["span-" + index][0];
        switch(this.sortDirection){
            case null:
                 this.sortDirection = 'asc';
                 targetSpan.textContent = "↑";
                 break;
            case 'asc':
                 this.sortDirection = 'desc';
                 targetSpan.textContent = "↓";
                 break;
            case 'desc':
                 this.sortDirection = null;
                 targetSpan.textContent = "";
                 break;
         }
    }
} 

方法2:数据驱动视图(Vue推荐方案)

避免直接操作DOM,通过绑定数据来控制文本内容:

  1. 在data中新增存储排序状态的数组:
data() {
  return {
    columns: [], // 你的列数据
    rows: [], // 你的行数据
    sortIndex: null,
    sortDirection: null,
    sortIcons: [] // 存储每列的排序文本/图标
  }
},
created() {
  // 初始化数组长度与列数一致,默认空文本
  this.sortIcons = new Array(this.columns.length).fill("");
}
  1. 修改模板绑定数据:
<th 
     v-for="(column, index) in columns"
     :key="index"
     @click="sortRecords(index)"
> 
    {{column}} <span>{{sortIcons[index]}}</span>
</th>
  1. 更新排序函数操作数据:
sortRecords (index) {
     if(this.sortIndex === index){
        switch(this.sortDirection){
            case null:
                 this.sortDirection = 'asc';
                 this.sortIcons[index] = "↑";
                 break;
            case 'asc':
                 this.sortDirection = 'desc';
                 this.sortIcons[index] = "↓";
                 break;
            case 'desc':
                 this.sortDirection = null;
                 this.sortIcons[index] = "";
                 break;
         }
    } else {
        // 切换列时重置状态
        this.sortIndex = index;
        this.sortDirection = 'asc';
        this.sortIcons.fill("");
        this.sortIcons[index] = "↑";
    }
    // 执行你的排序逻辑
} 

内容的提问来源于stack exchange,提问作者Petar Yakov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:05:53