Vue:限制文本区域输入中的字符,截断过滤器?

J W*_*J W 2 truncate vue.js vuejs2 v-model

<textarea name="" id="" cols="30" rows="10" v-model="$store.state.user.giftMessage | truncate 150"></textarea> 我尝试创建一个自定义过滤器:

filters: {
    truncate(text, stop, clamp) {
        return text.slice(0, stop) + (stop < text.length ? clamp || '...' : '')
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我将其放入输入的v模型中时,构建并没有中断...

有什么建议吗?

Alp*_*ons 8

很抱歉闯入。正在寻找解决方案。看着他们所有人。对我来说,它们看起来太复杂了。我一直在寻找共情。因此我喜欢@??????的答案 ??????。但它有@J。兰博指出了潜在的问题。

尽可能接近原生 html 文本元素。我想出的解决方案是:

Vue 模板

<textarea v-model="value" @input="assertMaxChars()">
Run Code Online (Sandbox Code Playgroud)

JavaScript

let app = new Vue({
  el: '#app',
  data: {
    value: 'Vue is working!',
    maxLengthInCars: 25
  },

  methods: {
    assertMaxChars: function () {
        if (this.value.length >= this.maxLengthInCars) {
            this.value = this.value.substring(0,this.maxLengthInCars);
        }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

这是一个 REPL 链接:https : //repl.it/@tsboh/LimitedCharsInTextarea

我看到的好处是:

  • 元素尽可能接近原生元素
  • 简单的代码
  • textarea 保持焦点
  • 删除仍然有效
  • 也适用于粘贴文本

无论如何快乐编码


Ber*_*ert 6

这是您确实要使用组件的情况之一。

这是一个呈现a textarea并限制文本量的示例组件

请注意:这尚未准备好生产,请处理所有角盒组件。仅作为示例。

Vue.component("limited-textarea", {
  props:{
    value:{ type: String, default: ""},
    max:{type: Number, default: 250}
  },
  template: `
    <textarea v-model="internalValue" @keydown="onKeyDown"></textarea>
  `,
  computed:{
    internalValue: {
      get() {return this.value},
      set(v){ this.$emit("input", v)}
    }
  },
  methods:{
    onKeyDown(evt){
      if (this.value.length >= this.max) {
        if (evt.keyCode >= 48 && evt.keyCode <= 90) {
          evt.preventDefault()
          return
        }
      }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

该组件实现v-model并且仅在文本的长度小于指定的最大值时才对数据发出更改。keydown如果文本的长度等于或大于允许的最大值,它将通过侦听并阻止默认操作(键入字符)来实现此目的。

Vue.component("limited-textarea", {
  props:{
    value:{ type: String, default: ""},
    max:{type: Number, default: 250}
  },
  template: `
    <textarea v-model="internalValue" @keydown="onKeyDown"></textarea>
  `,
  computed:{
    internalValue: {
      get() {return this.value},
      set(v){ this.$emit("input", v)}
    }
  },
  methods:{
    onKeyDown(evt){
      if (this.value.length >= this.max) {
        if (evt.keyCode >= 48 && evt.keyCode <= 90) {
          evt.preventDefault()
          return
        }
      }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
console.clear()

Vue.component("limited-textarea", {
  props:{
    value:{ type: String, default: ""},
    max:{type: Number, default: 250}
  },
  template: `
    <textarea v-model="internalValue" @keydown="onKeyDown"></textarea>
  `,
  computed:{
    internalValue: {
      get() {return this.value},
      set(v){ this.$emit("input", v)}
    }
  },
  methods:{
    onKeyDown(evt){
      if (this.value.length >= this.max) {
        if (evt.keyCode >= 48 && evt.keyCode <= 90) {
          evt.preventDefault()
          return
        }
      }
    }
  }
})

new Vue({
  el: "#app",
  data:{
    text: ""
  }
})
Run Code Online (Sandbox Code Playgroud)

问题中代码的另一个问题是Vuex不允许您直接设置状态值。您必须通过突变来做到这一点。也就是说,应该有一个接受新值并进行设置的Vuex突变,并且代码应提交该突变。

mutations: {
  setGiftMessage(state, message) {
    state.user.giftMessage = message
  }
}
Run Code Online (Sandbox Code Playgroud)

在您的Vue中:

computed:{
  giftMessage:{
    get(){return this.$store.state.user.giftMessage},
    set(v) {this.$store.commit("setGiftMessage", v)}
  }
}
Run Code Online (Sandbox Code Playgroud)

从技术上讲,代码应该使用a getter来吸引用户(这是giftMessage),但这应该可以工作。在模板中,您将使用:

<limited-textarea cols="30" rows="10" v-model="giftMessage"></limited-textarea>
Run Code Online (Sandbox Code Playgroud)

这是使用Vuex的完整示例。

<script src="https://unpkg.com/vue@2.4.2"></script>
<div id="app">
  <limited-textarea v-model="text" 
                    :max="10"
                    cols="30"
                    rows="10">
  </limited-textarea>
</div>
Run Code Online (Sandbox Code Playgroud)
mutations: {
  setGiftMessage(state, message) {
    state.user.giftMessage = message
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 还要注意,对于keyCode,实际上不是键1到0或字母az的字符仍会添加(范围48-&gt; 90之外的任何值) (3认同)