Home > Net >  Change the text of a <span> using $refs in Vue.js
Change the text of a <span> using $refs in Vue.js

Time:09-29

I have the following <span> element in my <template>.

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

How do I change the content of this <span> from my text to my new text using $refs in my <script> section? I tried all of the following two options, but with different attributes like innerHTML, innerText and text, but nothing worked.

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

When I use .span, I always get this error.

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

And if I don't use .span, it just adds another attribute to the object. Like in the following picture and the text of the <span> element stays unchanged. enter image description here

Here is my table:

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

And here is my function

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;
         }
    }
} 

Edit: I tried adding another <span> for a test that was outside of the v-for and .textContent worked fine. What I also noticed is that the object for the test span in the $refs looked different than those created in the for loop. The object is not shown in [] as the other. You can see it in the picture below.

enter image description here

CodePudding user response:

Try with this.$refs["span-" 1][0].[textContent]` :

new Vue({
  el: "#demo",
  data() {
  return{
    columns: [1,2,3,4],
    rows: [],
    sortDirection: 'asc',
    sortIndex: 1
  }},
  methods: {
   sortRecords(index) {
     if(this.sortIndex === index){
       switch(this.sortDirection){
         case null:
           this.sortDirection = 'asc';
           this.$refs["span-"   index][0].textContent = "my new text";
           break;
         case 'asc':
           this.sortDirection = 'desc';
           this.$refs["span-"   index][0].textContent = "my new text";
           break;
         case 'desc':
           this.sortDirection = null;
           this.$refs["span-"   index][0].textContent = "my new text";
           break;
       }
     }
    } 
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <table >
    <thead>
      <tr>
        <th 
           v-for="(column, index) in columns"
           v-bind:key="index"
           v-on:click="sortRecords(index)"
         > 
          {{column}} <span :ref="'span-'   index"></span>
        </th>
      </tr>                        
    </thead>
    <tbody>
       <tr
         v-for="(row, index) in rows"
         v-bind:key="index"
       >
          <td
            v-for="(rowItem, itemIndex) in row"
            v-bind:key="itemIndex"
          >
             {{rowItem}} 
          </td>
       </tr>                      
    </tbody>
</table>
</div>

  • Related