最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vuejs: Character Counter - Stack Overflow

programmeradmin2浏览0评论

I am trying to create a "twitter-like" character counter using Vuejs; however, I am encountering two separate issues.

  1. Error: Unable to get property 'length' of undefined or null reference
  2. Even if I get it to work, is there any way to call the same function using multiple events without adding each one as a separate call to the tag. Ex: v-on:keyup,blur,focus="limiter(this,140)"

HTML:

<div class="form-group" id="vue">
  <label for="eligibility-address-detail">Address Notes:</label>
  <textarea class="form-control" id="eligibility-address-detail" rows="3" 
   name="eligibility[address][detail]" v-model="eligibility.address.details" 
   v-on:keyup="limiter(this, 140)" required></textarea>
  <span class="limiter"></span>
</div>

JavaScript:

var main = new Vue({
  el: "#vue",
  data: {
    eligibility: {
      address: {
        details: ""
      }
    }       
  },
  methods: {        
      limit: function(elem, limit){
          var chars = elem.value.length;
          if (chars > limit) {
              elem.value = elem.value.substr(0, limit);
              chars = limit;
          }
          $(elem).siblings('.limiter').html((limit - chars) + " / " + limit + "characters remaining");
      }
  }
});

I am trying to create a "twitter-like" character counter using Vuejs; however, I am encountering two separate issues.

  1. Error: Unable to get property 'length' of undefined or null reference
  2. Even if I get it to work, is there any way to call the same function using multiple events without adding each one as a separate call to the tag. Ex: v-on:keyup,blur,focus="limiter(this,140)"

HTML:

<div class="form-group" id="vue">
  <label for="eligibility-address-detail">Address Notes:</label>
  <textarea class="form-control" id="eligibility-address-detail" rows="3" 
   name="eligibility[address][detail]" v-model="eligibility.address.details" 
   v-on:keyup="limiter(this, 140)" required></textarea>
  <span class="limiter"></span>
</div>

JavaScript:

var main = new Vue({
  el: "#vue",
  data: {
    eligibility: {
      address: {
        details: ""
      }
    }       
  },
  methods: {        
      limit: function(elem, limit){
          var chars = elem.value.length;
          if (chars > limit) {
              elem.value = elem.value.substr(0, limit);
              chars = limit;
          }
          $(elem).siblings('.limiter').html((limit - chars) + " / " + limit + "characters remaining");
      }
  }
});
Share Improve this question edited Apr 18, 2017 at 14:39 Neve12ende12 asked Apr 17, 2017 at 22:23 Neve12ende12Neve12ende12 1,1944 gold badges18 silver badges35 bronze badges 2
  • 2 I answered this pretty much exact question in Vue a while back. codepen.io/Kradek/pen/VpNvxg?editors=1010 stackoverflow./q/43217239/38065 – Bert Commented Apr 17, 2017 at 22:28
  • Looks like there is a problem in your ponent. In your HTML you have the following v-model="eligibility.address.details" but your data attribute does not have those properties. – Maurice Commented Apr 18, 2017 at 2:05
Add a ment  | 

1 Answer 1

Reset to default 9

In general, with most modern front-end frameworks (Angular, React, Vue, etc) you want to avoid manipulating and inspecting the DOM manually. The remended approach is to make everything data-driven (aka: use the model) and let the framework update the DOM when needed - this is a key concept behind the whole "reactivity system"

But here are a few remendations to fix your issue:

Do not call your limit() method on DOM events. Instead... look at the eligibility.address.details attribute which is are binding to the inputs v-model.

You can create a puted property that calculates the remaining characters based on that attribute.

puted: {
    charactersLeft() {
        var char = this.eligibility.address.details.length,
            limit = 140;

        return (limit - char) + " / " + limit + "characters remaining";
      }
}

Then in your markup, you would use the puted property like a regular data property:

<span class="limiter">{{charactersLeft}}</span>
发布评论

评论列表(0)

  1. 暂无评论