输入框识别组件

121 阅读2分钟

业务开发中发现,会经常发现有这样一个功能需求,通过一些标识符把一段文字分隔成字符串数组,如果一两个页面是这样的需求那还可以cv下,但是如果有多个页面都需要使用的话就要考虑拆分和封装,大致需求图如下 image.png 设计思想如下: 1.输入框的值可以由外部组件传入。(例如遇到缓存等场景) 2.分隔符规则可以自定义,然后生成动态的的正则表达式。 3.其他文本域属性例如(rows--最大展示行数)组件就不定义接受了,而是通过属性透传的方式绑定。

那么问题的核心点就是第二点:动态生成正则表达式,找gpt(AI编程可真不错~),方法如下

 *
 * @param {*} symbolsArray 传入的分隔符数组
 * @returns 返回一个正则
 */
export function createSeparatorRegex(symbolsArray) {
  const escapedSymbols = symbolsArray.map((symbol) => {
    // 对特殊字符进行转义
    return symbol.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
  })
  const regexPattern = `[${escapedSymbols.join('')}]`
  return new RegExp(regexPattern, 'g')
}

ok,核心问题解决,验证开始

  <div class="identify">
    <div class="input-content">
      <el-input
        v-model="inputValue"
        :placeholder="`请输入,并用空格、回车或逗号分隔`"
        v-bind="attrs"
        type="textarea"
        @change="emit('update:modelValue', e)"
      />
    </div>
    <div class="opt-buttons">
      <el-button size="small" type="primary" @click="identify">识别</el-button>
    </div>
  </div>
</template>
<script setup>
  // vue
  import { useAttrs } from 'vue'
  // utils
  import { createSeparatorRegex } from './index.js'

  // 除了props定义的两个自定义属性,其他属性直接透传过来
  const attrs = useAttrs()
  const emit = defineEmits(['identify', 'update:modelValue'])
  const props = defineProps({
    // 输入框的值,默认为空
    modelValue: {
      type: String,
      default: '',
    },
    // 分隔规则,非必传,默认值为空格,换行符,以及中英文逗号
    separateRules: {
      type: Object,
      default: () => [' ', '\n', ',', ','],
    },
  })
  const inputValue = ref(unref(props.modelValue))
  const regex = computed(() => {
    // 根据分隔符规则列表,动态返回对应的正则表达式
    return createSeparatorRegex(props.separateRules)
  })

  // 识别
  const identify = () => {
    emit('identify',{res:inputValue.value.split(unref(regex))})
  }
</script>

<style lang="scss" scoped>
  .identify {
    width: 100%;
    display: flex;
    flex-direction: column;
    row-gap: 10px;
    .input-content {
      width: 100%;
    }
    .opt-buttons {
      width: 100%;
      display: flex;
      justify-content: flex-end;
    }
  }
</style>

在父组件里引用

image.png 学习笔记,如有优化建议,请指教~