【问题标题】:Best way to select/highlight text (in text input) in Vue (using computed properties for value and selection range)在 Vue 中选择/突出显示文本(在文本输入中)的最佳方法(使用计算属性来计算值和选择范围)
【发布时间】:2021-04-10 19:01:27
【问题描述】:

目前我们有一个文本输入,其值存储在我们的 vuex 存储中,作为 props 传入并通过computed property 检索。在同一个 vuex 存储中,我们有一个选择范围(两个数字的数组),这将允许选择/突出显示输入中的文本。

这是代码的简化版本:

<template>
  <input type="text" v-model="value" @select="selectionHandler" />
</template>

<script>
  export default {
    props: ['props'],
    computed: {
      value: function() {
        return this.props.value // some string
      },
      selectionRange: {
        get: function () { return this.props.selectionRange }, // [number, number] 
        set: function (range) { /* dispatch store action to update, which will update props */ }
      }
    },
    methods: {
      selectionHandler(e) { 
        this.selectionRange = [e.currentTarget.selectionStart, e.currentTarget.selectionEnd]
      }
    }
  }
</script>

目标是选择/突出显示文本(来自商店)并根据用户选择的内容更新商店。我打算使用setSelectionRange (docs)。我想我可以使用refswatchers,但这似乎有点矫枉过正。

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    我最终创建了一个 select 函数并使用 refs 来选择输入/文本区域文本。最初我使用 Vue life cycle methods 调用 selectmountedupdated。所以简化版是这样的:

    <template>
      <input ref="someRefName" type="text" v-model="value" @select="selectionHandler" />
    </template>
    
    <script>
      export default {
        props: ['props'],
        computed: {
          value: function() {
            return this.props.value // some string
          },
          selectionRange: {
            get: function () { return this.props.selectionRange }, // [number, number] 
            set: function (range) { /* dispatch store action to update, which will update props */ }
          }
        },
        methods: {
          selectionHandler(e) { 
            this.selectionRange = [e.currentTarget.selectionStart, e.currentTarget.selectionEnd]
          },
          select() {
            this.$refs['someRefName'].setSelectionRange(this.selectionRange[0], this.selectionRange[1])
          }
        },
        mounted: function () {
          if (this.selectionRange[1] !== 0) { this.select() }
        },
        updated: function () {
          if (this.selectionRange[1] !== 0) { this.select() }
        }
      }
    </script>
    

    这似乎是一个很好的解决方案...直到我意识到“哦,这不是浏览器的工作方式。”每次输入失去焦点时,所选/突出显示的文本都会被清除。所以我把它改成了使用焦点和模糊处理函数。现在只有当元素处于焦点时才会选择文本。像这样的:

    <template>
      <input ref="someRefName" type="text" v-model="value" @focus="focusHandler" @select="selectionHandler" @blur="blurHandler" />
    </template>
    
    <script>
      export default {
        props: ['props'],
        computed: {
          value: function() {
            return this.props.value // some string
          },
          selectionRange: {
            get: function () { return this.props.selectionRange }, // [number, number] 
            set: function (range) { /* dispatch store action to update, which will update props */ }
          }
        },
        methods: {
          focusHandler() {
            if (this.selectionRange[1] !== 0) { this.select() }
          },
          selectionHandler(e) { 
            this.selectionRange = [e.currentTarget.selectionStart, e.currentTarget.selectionEnd]
          },
          blurHandler() {
            this.selectionRange = [0, 0]
          },
          select() {
            this.$refs['someRefName'].setSelectionRange(this.selectionRange[0], this.selectionRange[1])
          }
        }
      }
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-22
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多