해결된 질문
작성
·
2K
·
수정됨
2
vue에서는 한글 실시간 바인딩을 다음 코드로 합니다.
<template> <h1>{{ msg }}</h1>
<input type="text" :value="msg" @input="msg = $event.target.value" />
</template>
하지만 퀘이사의 q-input에서는 @input 이벤트가 디프리케이트 되어서 동작하지 않습니다.
한글 실시간 처리를 하려면 어떻게 해야할지요?
감사합니다.
답변 2
1
안녕하세요 :)
<q-input v-model="msg" />
또는
<q-input
:model-value="msg"
@update:model-value="value => (msg = value)"
/>
아래 링크를 참고하시면 이해하는데 도움이 되실거에요 :)
양방향 바인딩은 v-model
를 사용하는게 맞는데용 🤔
키보드 이벤트 처리를 하고 싶은데 한글이 정상동작을 안해서 문제가 되는걸까요?
그렇다면 @keypress
로 해보시겠어요?
<q-input
:value="modelval"
@keypress="evt => (modelval = evt.target.value)"
>
위 코드로 해봤지만 증상은 더 심각하게 업뎃조차 안되며 엔터쳐야 업뎃됩니다. (기존 v-model을 활용하면 커서가 옮겨지면 업뎃은 되었습니다.)
실제 개발은 아래 링크의 autocomplete를 구현하기 위한 q-select를 활용하고 있어서 문의드렸습니다.
https://quasar.dev/vue-components/select#native-attributes-with-use-input
기능 구현이 잘 안되서 현재는 그냥 hint에 엔터를 눌러달라는 안내문구만 추가하였습니다.
답변 감사합니다!
@keypress
를 말씀 드린건 키보드 이벤트 활용시 한글 이슈가 있으면 해보시라고 말씀드린거고요.
코드 전체를 보여주실 수 있으신가요?
setup
함수내에서 반응형 상태(const msg = ref('')
)를 선언하고
v-model
에서 잘 사용하셨으면 문제가 없어보이는데요.
<template>
<div class="q-pa-md">
<div class="q-gutter-md">
<q-select
filled
v-model="model"
clearable
use-input
hide-selected
fill-input
input-debounce="0"
label="Focus after filtering"
:options="options"
@filter="filterFn"
@filter-abort="abortFilterFn"
style="width: 250px"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey"> No results </q-item-section>
</q-item>
</template>
</q-select>
<q-select
filled
v-model="model"
clearable
use-input
hide-selected
fill-input
input-debounce="0"
label="Autoselect after filtering"
:options="options"
@filter="filterFnAutoselect"
@filter-abort="abortFilterFn"
style="width: 250px"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey"> No results </q-item-section>
</q-item>
</template>
</q-select>
</div>
</div>
</template>
<script>
import { ref } from 'vue';
const stringOptions = ['가나다', '마바사', '아자차', '테스트', '헤이루'].reduce(
(acc, opt) => {
for (let i = 1; i <= 5; i++) {
acc.push(opt + ' ' + i);
}
return acc;
},
[],
);
export default {
setup() {
const options = ref(stringOptions);
return {
model: ref(null),
options,
filterFn(val, update, abort) {
// call abort() at any time if you can't retrieve data somehow
setTimeout(() => {
update(
() => {
if (val === '') {
options.value = stringOptions;
} else {
const needle = val.toLowerCase();
options.value = stringOptions.filter(
v => v.toLowerCase().indexOf(needle) > -1,
);
}
},
// "ref" is the Vue reference to the QSelect
ref => {
if (val !== '' && ref.options.length > 0) {
ref.setOptionIndex(-1); // reset optionIndex in case there is something selected
ref.moveOptionSelection(1, true); // focus the first selectable option and do not update the input-value
}
},
);
}, 300);
},
filterFnAutoselect(val, update, abort) {
// call abort() at any time if you can't retrieve data somehow
setTimeout(() => {
update(
() => {
if (val === '') {
options.value = stringOptions;
} else {
const needle = val.toLowerCase();
options.value = stringOptions.filter(
v => v.toLowerCase().indexOf(needle) > -1,
);
}
},
// "ref" is the Vue reference to the QSelect
ref => {
if (
val !== '' &&
ref.options.length > 0 &&
ref.getOptionIndex() === -1
) {
ref.moveOptionSelection(1, true); // focus the first selectable option and do not update the input-value
ref.toggleOption(ref.options[ref.optionIndex], true); // toggle the focused option
}
},
);
}, 300);
},
abortFilterFn() {
// console.log('delayed filter aborted')
},
};
},
};
</script>
퀘이사 공식 홈페이지에서 autocomplete 예시를 가져와서 옵션값을 한글로만 바꾸었습니다.
테스트 글자를 입력해 보시면 테스트 끝까지 칠때까지 autocomplete가 동작하지 않습니다.
참고로 영어는 잘 됩니다.. 한글만 잘 안됩니다!ㅠ
귀중한 시간 내 주셔서 감사드립니다!
우선 위 코드에서 v-model="model"
값은 옵션(option)이 선택되었을때 변경되는게 맞겠죠?
그런데 한글 이슈가 있으신것 같은데요 🤔
(이벤트 처리에서 한글 이슈는 종종 생겨서요.)
처음에 질문하신 내용이랑은 다른 내용같은데요.
우선 선언되어있는 함수(filterFn
, filterFnAutoselect
)를 디버깅 해보셔야 할 거 같아요.
아니면 QSelect API에서 Events 탭을 보셔서 다른 이벤트로 처리할 수 있는지 확인 🥲
그리고 참고로 문제가 있는 부분을 찾고 해결하실때는 최대한 간결한코드로 하면 더 좋을 거 같아요~!
디버깅도 시도 해 보았고 기재되어 있는 모든 이벤트에 대하여 테스트를 해보았는데 결국 적절한 해결책을 찾지 못해 질문을 드려 봤습니다.
한글 이슈가 조금 아쉽긴 하네요.ㅠㅠ 귀중한 시간 내 주셔서 감사드립니다!
ps. 위 예제는 공식 홈페이지 예제이며 옵션만 한글로 변경하였습니다. 공식 홈페이지 예제가 가장 잘 짜여진 코드이니 축소없이 올려드린점 양해 부탁 드립니다!
<template>
<q-select ref="qSelectRef" use-input> </q-select>
</template>
<script>
import { onMounted, ref } from 'vue';
export default {
setup() {
const qSelectRef = ref(null);
onMounted(() => {
qSelectRef.value.$el
.querySelector('input')
.addEventListener('input', function (e) {
console.log(e.target.value);
});
});
return {
qSelectRef,
};
},
};
</script>
Template Refs를 활용하여 Native Element($el
) 를 가져오신 후 addEventListener
를 활용하시면 이슈가 해결될 거 같은데요?
한번 해보시겠어요?
해당 코드로 이것저것 tricky하게 건드려서 autocomplete q-select 성공했습니다!
선생님과 수강생분들께도 참고하시라 코드 공유 드립니다.
귀중한 시간 내어주셔서 감사합니다.
<template>
<div class="q-pa-md">
<div class="row q-gutter-md">
<q-select
filled
clearable
use-input
hide-selected
fill-input
ref="qSelectRef"
v-model="modeldummy"
:value="model"
:options="options"
style="width: 250px"
@input-value="updateVal"
>
</q-select>
<p>Text: {{ model }}</p>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const stringOptions = ['가나다', '마바사', '아자차', '테스트', 'google'].reduce(
(acc, opt) => {
for (let i = 1; i <= 5; i++) {
acc.push(opt + ' ' + i);
}
return acc;
},
[],
);
const options = ref(stringOptions);
const qSelectRef = ref(null);
const model = ref(null);
const modeldummy = ref(null);
onMounted(() => {
qSelectRef.value.$el
.querySelector('input')
.addEventListener('input', function (e) {
console.log(e.target.value);
model.value = e.target.value;
if (model.value === '') {
options.value = stringOptions;
} else {
const needle = model.value.toLowerCase();
options.value = stringOptions.filter(
v => v.toLowerCase().indexOf(needle) > -1,
);
console.log('options', options.value);
}
if (
model.value !== '' &&
qSelectRef.value.options.length > 0 &&
qSelectRef.value.getOptionIndex() === -1
) {
qSelectRef.value.moveOptionSelection(1, true); // focus the first selectable option and do not update the input-value
qSelectRef.value.toggleOption(
qSelectRef.value.options[qSelectRef.value.optionIndex],
true,
); // toggle the focused option
}
});
});
const updateVal = val => {
model.value = val;
};
</script>
0
### Quasar Input 한글 IME 이슈
이미 해결하신 질문이지만, 공유차원에 내용을 추가합니다.
### 개발환경
- 맥, 크롬 , 사파리
- quasar : 2.6.0
- vue : 3.0.0
### 증상
- Vue3에서 해결됬다는 한글 input IME 이슈가 Quasar q-input 에서 발생
- 강사님께서 제시하신 방법 적용해봤으나, 전부 오동작(@update:model-value, @keypress)
### 해결방법
- q-input tag에 ref를 먹여 onMount 시 해당 태그에서 리스너를 등록하여 상태를 갱신
<q-input
ref="qInputRef"
dense
color="primary"
label="searchKeyword"
:model-value="searchKeyword"
>
</q-input>
onMounted(() => {
console.log('onMounted');
const el = qInputRef.value.getNativeElement();
el.addEventListener('input', e => {
console.log('input', e.target.value);
searchKeyword.value = e.target.value;
});
initPage();
});
react를 조금 해본 입장에서, 좀 편하게 쓸려고 vue Quasar를 써볼까 했는데... 이런 기본적인게 안되니 안타깝네요.
### 문제해결 참고자료
https://stove99.github.io/javascript/2021/06/29/quasar-v2-q-input-ime/
답변 감사합니다.
동일한 방식대로 했을때 아래 블로그처럼 실시간 한글 바인딩이 되지 않습니다.ㅠ
https://webruden.tistory.com/485
제가 디프리케이드 안된 @keyup 방식으로도 해봤지만 한글이 깨집니다. (예를들면 "대구"로 타이핑 하지만 변수에는 "댁구")
@input을 사용해야 할꺼 같은데 방법이 없을까요?
GPT에도 질의해봤지만 @input방식만 알려줍니다.