0

我正在处理一个投资组合项目,用户可以在其中上传图片,在其下方提供描述,然后单击“添加”按钮添加另一个图像和描述。

我正在尝试将字符计数器添加到描述输入中,这是一个textarea字段。通常我可以将名称添加v-model到函数中,它工作正常,但这textarea是在一个for循环中,所以我不确定如何让这个函数工作。

模板:

<div class="newPortfolioList">
    <div class="newPortfolioItem" v-for="(item, index) in this.portfolioItems" v-bind:key="index">
....
       <div class="newPortfolioDescription">
          <textarea v-model="item.portfolioDescription" @keyup='remaincharCount()' maxlength="1000" placeholder="Item Description..."></textarea>
       </div>

       <!--  Displaying the remaining characters -->
       <span style="text-align:left; padding: 10px;">{{ remaincharactersText }}</span>
    </div>
...         

脚本:

export default {
    data () {
        return {
            portfolioItems:[],
            maxcharacter: 1000,
            remaincharactersText: "1000 characters remaining"            
        }
    },
    methods: {
        createPortfolioItem () {
            this.portfolioItems.push({
                portfolioDescription: ''
            })
        },
        remaincharCount () {
            if (this.foo.length > this.maxcharacter) {
              this.remaincharactersText = "Exceeded "+this.maxcharacter+" characters limit.";
            } else {
              var remainCharacters = this.maxcharacter - this.foo.length;
              this.remaincharactersText = remainCharacters + " characters remaining";
            }
        }
    }
}
4

2 回答 2

2

有很多方法可以做到这一点。

在这种情况下,我认为您最好的选择是引入一个新组件来表示单个投资组合项目。这些组件中的每一个都可以管理自己的消息。从他们的角度来看,没有需要考虑的循环。

所以你的列表模板会有这样的东西:

<div class="newPortfolioList">
    <my-new-portfolio-item
        v-for="(item, index) in portfolioItems"
        :key="index"
        :portfolio-item="item"
    />
</div>

两个旁注。我已经去掉了v-bind你钥匙上的前缀,一个:就足够了。我也删除了this.之前portfolioItems的,因为这也是不必要的。Vue linting 规则可用于帮助检查这些内容。

除了引入新组件之外,还有其他选择。您可以在模板中生成 的值,remaincharactersText而不是将其保持在状态中。它仍然可以是方法调用,但不会预先计算。像这样的东西:

<span style="text-align:left; padding: 10px;">{{ remaincharCount(item) }}</span>

另一种(甚至更痛苦)的替代方法是创建remaincharactersText一个值数组,然后通过索引获取相关的值:

<span style="text-align:left; padding: 10px;">{{ remaincharactersText[index] }}</span>

但是,重申一下,为 中的项目引入一个单独的组件v-for可能是最好的方法。

于 2019-05-11T21:41:42.827 回答
1

您应该知道 textarea 已经maxlength设置为 1000,所以标签Exceeded N characters limit是不可能的(除非您检查少于 1000)。目前,标签总是会显示N reminaing characters.

选项 1:内联显示计数计算

您可以使用字符串插值内联显示计算,而不是存储字符数(不必要地占用额外的内存):

<template>
  <div>
    <textarea v-model="item.portfolioDescription" maxlength="1000"></textarea>
    <span>{{ 1000 - item.portfolioDescription.length }} remaining characters</span>
  </div>
</template>

演示 1

选项 2:显示项目变量的计数

如果您更喜欢存储字符数(例如,用于某些内部处理),您可以向项目数据添加一个新属性:

<script>
const MAXLEN = 1000

export default {
  methods: {
    createPortfolioItem() {
      this.portfolioItems.push({
        remainChars: MAXLEN, // <--
      })
    },
  }
}
</script>

然后,更新's item.remainChars-event ,并显示内联。textareainputitem.remainChars

<template>
  <div>
    <textarea v-model="item.portfolioDescription" maxlength="1000"
              @input="item.remainChars = 1000 - item.portfolioDescription.length">
    </textarea>
    <span>{{ item.remainChars }} remaining characters</span>
  </div>
</template>

演示 2

选项 3:显示计算文本

您可以在对应于的单独数组中计算portfolioItems字符数标签:

<script>
const MAXLEN = 1000

export default {
  computed: {
    remainingCharsText() {
      return this.portfolioItems.map(item => `${MAXLEN - item.portfolioDescription.length} remaining characters`)
    },
  }
}
</script>

然后,更新您的模板以通过以下方式引用此计算数组index

<template>
  <div>
    <textarea v-model="item.portfolioDescription" maxlength="1000">
    </textarea>
    <span>{{ remainingCharsText[index] }}</span>
  </div>
</template>

演示 3

于 2019-05-11T22:10:54.483 回答