1. 程式人生 > >實現一個可以實時提示的textarea

實現一個可以實時提示的textarea

arr 輸入 dropdown 實時 this template split max del

該組件輸入、換行、變換光標可以實時給出提示

效果:

技術分享圖片

textarea.vue

技術分享圖片
<template>
  <div>
    <el-input
      id="user-input"
      type="textarea" 
      placeholder="請換行輸入不同的通知用戶" 
      :autosize="{minRows: 2, maxRows: 10}" 
      v-model="inputValue" 
      @blur="closeHint"
      @input="settingHint"
      @click.native
="settingHint" @keyup.native="disposeKey"> </el-input> <input-hint :all-items="hintItems" :position = ‘hintPosition‘ @select = "replaceStr" ></input-hint> </div> </template> <script lang="ts"> import { Vue, Component, Prop } from
"vue-property-decorator"; import InputHint from "./inputHint.vue"; import $ from "jquery"; @Component({ components: { InputHint } }) export default class AdvancedTextarea extends Vue { inputValue: string = ‘‘; Seprator = "\n"; allUsers: string[] = []; hintItems: string[] = []; //傳入提示框的項,可以是html字符串;為空則表示不顯示提示框
initPosition = { //輸入框的信息,用於計算提示框位置 left: 15, top: 5, rowHeight: 20, //一行的高度 fontSize: 7 //一個字的寬度 } hintPosition = { left: this.initPosition.left, top: this.initPosition.top } //按上下左右鍵時,重置提示框 disposeKey(e) { if (e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40) { this.settingHint(); } } settingHint(val?) { let cursorLocation = $(#user-input).caret(); //光標位置 let newStr = this.inputValue.slice(0, cursorLocation); //輸入框光標前的字符 let newArr = newStr.split(this.Seprator); let searchKey = newArr.length === 0 ? "" : newArr[newArr.length - 1]; let regExp = new RegExp(searchKey, ig); this.hintItems = searchKey ? this.allUsers.filter(item => item.indexOf(searchKey) !== -1).map(item => item.replace(regExp, `<strong>${searchKey}</strong>`)) : this.allUsers; this.hintPosition.left = this.initPosition.left + this.initPosition.fontSize * (searchKey.length > 0 ? searchKey.length - 1 : 0); this.hintPosition.top = this.initPosition.top + this.initPosition.rowHeight * (newArr.length > 10 ? 10 : newArr.length); } closeHint() { //延後關閉是因為立即關閉的話,點擊提示框內容就無法觸發點擊事件 window.setTimeout(() => { this.hintItems = null; window.clearTimeout(); }, 200); } //將光標當前值替換為選中值 replaceStr(val) { let cursorLocation = $(#user-input).caret(); //光標位置 let newStr = this.inputValue.slice(0, cursorLocation); //輸入框光標前的字符 let row = newStr.split(this.Seprator).length - 1; //光標所在行 let oriArr = this.inputValue.split(this.Seprator); oriArr[row] = val; this.inputValue = oriArr.join(this.Seprator); $(#user-input).focus(); } getAllUsers() { this.allUsers = [ [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], ] } mounted() { if (this.allUsers.length === 0) { this.getAllUsers(); } } } </script>
View Code

inputHint.vue

技術分享圖片
<template>
  <div v-show="allItems&&allItems.length!==0">
    <ul class="el-dropdown-menu el-popper max-height new-scoll-bar" :style="{left: position.left+‘px‘, top: position.top+‘px‘}">
        <li class="el-dropdown-menu__item" v-for="(item,index) in allItems" :key="index" v-html="item" @click="selectItem(item)"></li>
    </ul>
  </div>
</template>

<style lang="postcss" scoped>
.max-height {
  max-height: 250px;
  overflow-y: auto;
}
</style>

<script lang="ts">
import { Vue, Component } from "vue-property-decorator";

@Component({
  props: {
    allItems: {
      type: Array,
      default: []
    },
    position: {
      type: Object,
      default: {
        left: 0,
        top: 0
      }
    }
  }
})

export default class InputHint extends Vue {
  allItems = this.allItems;
  selectItem(item: string) {
    let regExp = /<strong>|<\/strong>/g;
    let str = item.replace(regExp, ‘‘);
    this.$emit(select, str)
  }
}
</script>
View Code

實現一個可以實時提示的textarea