Как приложение vuejs может отобразить компонент в месте расположения курсора textarea?

1

Я хочу создать компонент vuejs следующим образом.
При вводе textarea textarea должно показывать рекомендуемые слова.
Например, когда пользователь вводит s, он должен показать, что список dorpdown включает в себя слова, которые начинаются с s в месте расположения курсора textarea поля.
Это возможно?
Если возможно, как это можно реализовать?

  • 0
    Используйте @input="myLookupFunc" в своей текстовой области. myLookupFunc будет искать в вашем файле слов / db слова, начинающиеся / содержащие подстроку, начинающиеся после последнего пробела и заканчивающиеся на вашем последнем набранном символе (используйте для этого регулярное выражение). Храните их в words собственности. Передайте words качестве опоры для вашего всплывающей подсказки. Покажите это, если words.length > 0 . Позиционирование до CSS.
  • 0
    Если вы найдете библиотеку js, которая уже выполняет эту функцию, вы можете создать директиву для использования библиотеки lib с Vue.
Показать ещё 1 комментарий
Теги:
vue.js

1 ответ

0
Лучший ответ

Невозможно обнаружить позицию курсора, но я смоделировал вашу идею, используя Vue.js и CSS, и я решил сделать это, вы можете ее улучшить

Vue.component('autocomplete', {
          data() {
		return {
			content: "",
			words: [
			"lorem",
			"ipsum",
			"dolor",
			"sit",
			"amet",
			"consectetur",
			"adipisicing",
			"elit"
			],
			showAutoCompl:false
			
		};
	},
	computed: {
		contentWords(){
			return this.content.split(/ |\r|\r\n|\n/)
		}
		,
		foundWords() {
			return this.words.filter(word => {
				return this.contentWords[this.contentWords.length-1] ? word.startsWith(this.contentWords[this.contentWords.length-1]) : "";
				
			});
		},
		lines(){
			return  this.content.split(/\r|\r\n|\n/);
		}

	},
	methods: {
		
		typeText(e) {
			
			this.content && this.foundWords.length?this.showAutoCompl=true:this.showAutoCompl=false;
			var div = document.getElementById("autocmpl");
			div.style.marginLeft = (10 + this.lines[this.lines.length-1].length * 7)+ "px";
			div.style.marginTop = ( this.lines.length * 8 )+ "px";
			
		},
		chooseWord(word){
     //    console.log(this.content.lastIndexOf("\n"))

     if(this.content.search("\n")===-1){
     	this.content = this.content.substring(0,this.content.lastIndexOf(" ")+1)+ word;
     }else if(this.content.lastIndexOf(" ")>this.content.lastIndexOf("\n")) {
     	this.content = this.content.substring(0,this.content.lastIndexOf(" ")+1)+ word;

     }else{
     	this.content = this.content.substring(0,this.content.lastIndexOf("\n")+1)+ word;

     }
     this.showAutoCompl=false;
 }

},
  template: '	<div >
		<div class="autocomplete" id="autocmpl" v-show="showAutoCompl">
			<div class="autocomplete-item" v-for="word in foundWords" @click="chooseWord(word)">
				{{word}} 
			</div>
		</div>
		<textarea  @input="typeText" id="textarea1" cols="50" rows="10" v-model="content">
		</textarea>
	</div>
'
})



new Vue({
  el: "#app"
 
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}


.autocomplete {
	margin: 0;
	margin-left: 10px;

	padding: 10px;
	box-shadow: 1px 1px 5px #444;
	background: #fff;
	position: absolute;
	z-index: 5;
}
.autocomplete-item {
	padding: 5px;
	cursor: pointer;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

<div id="app">
<autocomplete></autocomplete>
</div>

Следующий код предназначен для компонента одного файла:

<template>
	<div >
		<div class="autocomplete" id="autocmpl" v-show="showAutoCompl">
			<div class="autocomplete-item" v-for="word in foundWords" @click="chooseWord(word)">
				{{word}} 
			</div>
		</div>
		<textarea  @input="typeText" id="textarea1" cols="50" rows="10" v-model="content">
		</textarea>
	</div>

</template>

<script>
export default {
	data() {
		return {
			content: "",
			words: [
			"lorem",
			"ipsum",
			"dolor",
			"sit",
			"amet",
			"consectetur",
			"adipisicing",
			"elit"
			],
			showAutoCompl:false
			
		};
	},
	computed: {
		contentWords(){
			return this.content.split(/ |\r|\r\n|\n/)
		}
		,
		foundWords() {
			return this.words.filter(word => {
				return this.contentWords[this.contentWords.length-1] ? word.startsWith(this.contentWords[this.contentWords.length-1]) : "";
				
			});
		},
		lines(){
			return  this.content.split(/\r|\r\n|\n/);
		}

	},
	methods: {
		
		typeText(e) {
			
			this.content && this.foundWords.length?this.showAutoCompl=true:this.showAutoCompl=false;
			var div = document.getElementById("autocmpl");
			div.style.marginLeft = (10 + this.lines[this.lines.length-1].length * 7)+ "px";
			div.style.marginTop = ( this.lines.length * 8 )+ "px";
			
		},
		chooseWord(word){
     //    console.log(this.content.lastIndexOf("\n"))

     if(this.content.search("\n")===-1){
     	this.content = this.content.substring(0,this.content.lastIndexOf(" ")+1)+ word;
     }else if(this.content.lastIndexOf(" ")>this.content.lastIndexOf("\n")) {
     	this.content = this.content.substring(0,this.content.lastIndexOf(" ")+1)+ word;

     }else{
     	this.content = this.content.substring(0,this.content.lastIndexOf("\n")+1)+ word;

     }
     this.showAutoCompl=false;
 }

}
};
</script>

<style>
.autocomplete {
	margin: 0;
	margin-left: 10px;

	padding: 10px;
	box-shadow: 1px 1px 5px #444;
	background: #fff;
	position: absolute;
	z-index: 5;
}
.autocomplete-item {
	padding: 5px;
	cursor: pointer;
}
</style>
  • 0
    После ввода нескольких строк разрыва (\ n) он не отображается в правильном месте.
  • 0
    я не мог хороший способ установить маржу в зависимости от количества строк
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню